Merge branch 'dev-widget' into release-1.4

Conflicts:
	calculatorpp/AndroidManifest.xml
This commit is contained in:
Sergey Solovyev 2012-10-20 16:27:08 +04:00
commit 5f800daa25
93 changed files with 2538 additions and 1150 deletions

View File

@ -0,0 +1,13 @@
package org.solovyev.android.calculator;
/**
* User: Solovyev_S
* Date: 19.10.12
* Time: 17:31
*/
public final class CalculatorButtonActions {
private CalculatorButtonActions() {
throw new AssertionError();
}
}

View File

@ -5,12 +5,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import java.io.Serializable;
/** /**
* User: serso * User: serso
* Date: 9/20/12 * Date: 9/20/12
* Time: 9:50 PM * Time: 9:50 PM
*/ */
public interface CalculatorDisplayViewState { public interface CalculatorDisplayViewState extends Serializable {
@NotNull @NotNull
String getText(); String getText();

View File

@ -13,11 +13,19 @@ import org.solovyev.common.text.StringUtils;
*/ */
public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewState { public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewState {
/*
**********************************************************************
*
* FIELDS
*
**********************************************************************
*/
@NotNull @NotNull
private JsclOperation operation = JsclOperation.numeric; private JsclOperation operation = JsclOperation.numeric;
@Nullable @Nullable
private Generic result; private transient Generic result;
@Nullable @Nullable
private String stringResult = ""; private String stringResult = "";
@ -29,6 +37,14 @@ public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewStat
private int selection = 0; private int selection = 0;
/*
**********************************************************************
*
* CONSTRUCTORS
*
**********************************************************************
*/
private CalculatorDisplayViewStateImpl() { private CalculatorDisplayViewStateImpl() {
} }
@ -62,6 +78,14 @@ public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewStat
return calculatorDisplayState; return calculatorDisplayState;
} }
/*
**********************************************************************
*
* METHODS
*
**********************************************************************
*/
@NotNull @NotNull
@Override @Override
public String getText() { public String getText() {

View File

@ -1,309 +1,311 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.history.EditorHistoryState; import org.solovyev.android.calculator.history.EditorHistoryState;
import org.solovyev.common.gui.CursorControl; import org.solovyev.common.gui.CursorControl;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.text.StringUtils;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 21.09.12 * Date: 21.09.12
* Time: 11:53 * Time: 11:53
*/ */
public class CalculatorEditorImpl implements CalculatorEditor { public class CalculatorEditorImpl implements CalculatorEditor {
@Nullable @Nullable
private CalculatorEditorView view; private CalculatorEditorView view;
@NotNull @NotNull
private final Object viewLock = new Object(); private final Object viewLock = new Object();
@NotNull @NotNull
private CalculatorEditorViewState lastViewState = CalculatorEditorViewStateImpl.newDefaultInstance(); private CalculatorEditorViewState lastViewState = CalculatorEditorViewStateImpl.newDefaultInstance();
@NotNull @NotNull
private final Calculator calculator; private final Calculator calculator;
@NotNull @NotNull
private final CalculatorEventHolder lastEventHolder; private final CalculatorEventHolder lastEventHolder;
@NotNull @NotNull
private final CursorControlAdapter cursorControlAdapter = new CursorControlAdapter(this); private final CursorControlAdapter cursorControlAdapter = new CursorControlAdapter(this);
public CalculatorEditorImpl(@NotNull Calculator calculator) { public CalculatorEditorImpl(@NotNull Calculator calculator) {
this.calculator = calculator; this.calculator = calculator;
this.calculator.addCalculatorEventListener(this); this.calculator.addCalculatorEventListener(this);
this.lastEventHolder = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId()); this.lastEventHolder = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId());
} }
@Override @Override
public void setView(@Nullable CalculatorEditorView view) { public void setView(@Nullable CalculatorEditorView view) {
synchronized (viewLock) { synchronized (viewLock) {
this.view = view; this.view = view;
if ( view != null ) { if ( view != null ) {
view.setState(lastViewState); view.setState(lastViewState);
} }
} }
} }
@NotNull @NotNull
@Override @Override
public CalculatorEditorViewState getViewState() { public CalculatorEditorViewState getViewState() {
return lastViewState; return lastViewState;
} }
@Override @Override
public void updateViewState() { public void updateViewState() {
setViewState(this.lastViewState, false); setViewState(this.lastViewState, false);
} }
@Override @Override
public void setViewState(@NotNull CalculatorEditorViewState newViewState) { public void setViewState(@NotNull CalculatorEditorViewState newViewState) {
setViewState(newViewState, true); setViewState(newViewState, true);
} }
private void setViewState(@NotNull CalculatorEditorViewState newViewState, boolean fireEvent) { private void setViewState(@NotNull CalculatorEditorViewState newViewState, boolean majorChanges) {
synchronized (viewLock) { synchronized (viewLock) {
final CalculatorEditorViewState oldViewState = this.lastViewState; final CalculatorEditorViewState oldViewState = this.lastViewState;
this.lastViewState = newViewState; this.lastViewState = newViewState;
if (this.view != null) { if (this.view != null) {
this.view.setState(newViewState); this.view.setState(newViewState);
} }
if (fireEvent) { if (majorChanges) {
calculator.fireCalculatorEvent(CalculatorEventType.editor_state_changed, new CalculatorEditorChangeEventDataImpl(oldViewState, newViewState)); calculator.fireCalculatorEvent(CalculatorEventType.editor_state_changed, new CalculatorEditorChangeEventDataImpl(oldViewState, newViewState));
} } else {
} calculator.fireCalculatorEvent(CalculatorEventType.editor_state_changed_light, new CalculatorEditorChangeEventDataImpl(oldViewState, newViewState));
} }
}
@Override }
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorEventType calculatorEventType, @Override
@Nullable Object data) { public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
final CalculatorEventHolder.Result result = lastEventHolder.apply(calculatorEventData); @NotNull CalculatorEventType calculatorEventType,
@Nullable Object data) {
if (result.isNewAfter()) { final CalculatorEventHolder.Result result = lastEventHolder.apply(calculatorEventData);
switch (calculatorEventType) {
case use_history_state: if (result.isNewAfter()) {
final CalculatorHistoryState calculatorHistoryState = (CalculatorHistoryState)data; switch (calculatorEventType) {
final EditorHistoryState editorState = calculatorHistoryState.getEditorState(); case use_history_state:
this.setText(StringUtils.getNotEmpty(editorState.getText(), ""), editorState.getCursorPosition()); final CalculatorHistoryState calculatorHistoryState = (CalculatorHistoryState)data;
break; final EditorHistoryState editorState = calculatorHistoryState.getEditorState();
} this.setText(StringUtils.getNotEmpty(editorState.getText(), ""), editorState.getCursorPosition());
} break;
} }
}
/* }
**********************************************************************
* /*
* SELECTION **********************************************************************
* *
********************************************************************** * SELECTION
*/ *
**********************************************************************
@NotNull */
private CalculatorEditorViewState newSelectionViewState(int newSelection) {
if (this.lastViewState.getSelection() != newSelection) { @NotNull
final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newSelection(this.lastViewState, newSelection); private CalculatorEditorViewState newSelectionViewState(int newSelection) {
setViewState(result, false); if (this.lastViewState.getSelection() != newSelection) {
return result; final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newSelection(this.lastViewState, newSelection);
} else { setViewState(result, false);
return this.lastViewState; return result;
} } else {
} return this.lastViewState;
}
@NotNull }
public CalculatorEditorViewState setCursorOnStart() {
synchronized (viewLock) { @NotNull
return newSelectionViewState(0); public CalculatorEditorViewState setCursorOnStart() {
} synchronized (viewLock) {
} return newSelectionViewState(0);
}
}
@NotNull
public CalculatorEditorViewState setCursorOnEnd() {
synchronized (viewLock) { @NotNull
return newSelectionViewState(this.lastViewState.getText().length()); public CalculatorEditorViewState setCursorOnEnd() {
} synchronized (viewLock) {
} return newSelectionViewState(this.lastViewState.getText().length());
}
@NotNull }
public CalculatorEditorViewState moveCursorLeft() {
synchronized (viewLock) { @NotNull
if (this.lastViewState.getSelection() > 0) { public CalculatorEditorViewState moveCursorLeft() {
return newSelectionViewState(this.lastViewState.getSelection() - 1); synchronized (viewLock) {
} else { if (this.lastViewState.getSelection() > 0) {
return this.lastViewState; return newSelectionViewState(this.lastViewState.getSelection() - 1);
} } else {
} return this.lastViewState;
} }
}
@NotNull }
public CalculatorEditorViewState moveCursorRight() {
synchronized (viewLock) { @NotNull
if (this.lastViewState.getSelection() < this.lastViewState.getText().length()) { public CalculatorEditorViewState moveCursorRight() {
return newSelectionViewState(this.lastViewState.getSelection() + 1); synchronized (viewLock) {
} else { if (this.lastViewState.getSelection() < this.lastViewState.getText().length()) {
return this.lastViewState; return newSelectionViewState(this.lastViewState.getSelection() + 1);
} } else {
} return this.lastViewState;
} }
}
@NotNull }
@Override
public CursorControl asCursorControl() { @NotNull
return cursorControlAdapter; @Override
} public CursorControl asCursorControl() {
return cursorControlAdapter;
/* }
**********************************************************************
* /*
* EDITOR ACTIONS **********************************************************************
* *
********************************************************************** * EDITOR ACTIONS
*/ *
**********************************************************************
@NotNull */
@Override
public CalculatorEditorViewState erase() { @NotNull
synchronized (viewLock) { @Override
int selection = this.lastViewState.getSelection(); public CalculatorEditorViewState erase() {
final String text = this.lastViewState.getText(); synchronized (viewLock) {
if (selection > 0 && text.length() > 0 && selection <= text.length()) { int selection = this.lastViewState.getSelection();
final StringBuilder newText = new StringBuilder(text.length() - 1); final String text = this.lastViewState.getText();
newText.append(text.substring(0, selection - 1)).append(text.substring(selection, text.length())); if (selection > 0 && text.length() > 0 && selection <= text.length()) {
final StringBuilder newText = new StringBuilder(text.length() - 1);
final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(newText.toString(), selection - 1); newText.append(text.substring(0, selection - 1)).append(text.substring(selection, text.length()));
setViewState(result);
return result; final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(newText.toString(), selection - 1);
} else { setViewState(result);
return this.lastViewState; return result;
} } else {
} return this.lastViewState;
} }
}
@NotNull }
@Override
public CalculatorEditorViewState clear() { @NotNull
synchronized (viewLock) { @Override
return setText(""); public CalculatorEditorViewState clear() {
} synchronized (viewLock) {
} return setText("");
}
@NotNull }
@Override
public CalculatorEditorViewState setText(@NotNull String text) { @NotNull
synchronized (viewLock) { @Override
final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(text, text.length()); public CalculatorEditorViewState setText(@NotNull String text) {
setViewState(result); synchronized (viewLock) {
return result; final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(text, text.length());
} setViewState(result);
} return result;
}
@NotNull }
@Override
public CalculatorEditorViewState setText(@NotNull String text, int selection) { @NotNull
synchronized (viewLock) { @Override
selection = correctSelection(selection, text); public CalculatorEditorViewState setText(@NotNull String text, int selection) {
synchronized (viewLock) {
final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(text, selection); selection = correctSelection(selection, text);
setViewState(result);
return result; final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(text, selection);
} setViewState(result);
} return result;
}
@NotNull }
@Override
public CalculatorEditorViewState insert(@NotNull String text) { @NotNull
synchronized (viewLock) { @Override
return insert(text, 0); public CalculatorEditorViewState insert(@NotNull String text) {
} synchronized (viewLock) {
} return insert(text, 0);
}
@NotNull }
@Override
public CalculatorEditorViewState insert(@NotNull String text, int selectionOffset) { @NotNull
synchronized (viewLock) { @Override
final int selection = this.lastViewState.getSelection(); public CalculatorEditorViewState insert(@NotNull String text, int selectionOffset) {
final String oldText = this.lastViewState.getText(); synchronized (viewLock) {
final int selection = this.lastViewState.getSelection();
int newTextLength = text.length() + oldText.length(); final String oldText = this.lastViewState.getText();
final StringBuilder newText = new StringBuilder(newTextLength);
int newTextLength = text.length() + oldText.length();
newText.append(oldText.substring(0, selection)); final StringBuilder newText = new StringBuilder(newTextLength);
newText.append(text);
newText.append(oldText.substring(selection)); newText.append(oldText.substring(0, selection));
newText.append(text);
int newSelection = correctSelection(text.length() + selection + selectionOffset, newTextLength); newText.append(oldText.substring(selection));
final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(newText.toString(), newSelection);
setViewState(result); int newSelection = correctSelection(text.length() + selection + selectionOffset, newTextLength);
return result; final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newInstance(newText.toString(), newSelection);
} setViewState(result);
} return result;
}
@NotNull }
@Override
public CalculatorEditorViewState moveSelection(int offset) { @NotNull
synchronized (viewLock) { @Override
int selection = this.lastViewState.getSelection() + offset; public CalculatorEditorViewState moveSelection(int offset) {
synchronized (viewLock) {
return setSelection(selection); int selection = this.lastViewState.getSelection() + offset;
}
} return setSelection(selection);
}
@NotNull }
@Override
public CalculatorEditorViewState setSelection(int selection) { @NotNull
synchronized (viewLock) { @Override
selection = correctSelection(selection, this.lastViewState.getText()); public CalculatorEditorViewState setSelection(int selection) {
synchronized (viewLock) {
final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newSelection(this.lastViewState, selection); selection = correctSelection(selection, this.lastViewState.getText());
setViewState(result, false);
return result; final CalculatorEditorViewState result = CalculatorEditorViewStateImpl.newSelection(this.lastViewState, selection);
} setViewState(result, false);
} return result;
}
private int correctSelection(int selection, @NotNull String text) { }
return correctSelection(selection, text.length());
} private int correctSelection(int selection, @NotNull String text) {
return correctSelection(selection, text.length());
private int correctSelection(int selection, int textLength) { }
int result = Math.max(selection, 0);
result = Math.min(result, textLength); private int correctSelection(int selection, int textLength) {
return result; int result = Math.max(selection, 0);
} result = Math.min(result, textLength);
return result;
private static final class CursorControlAdapter implements CursorControl { }
@NotNull private static final class CursorControlAdapter implements CursorControl {
private final CalculatorEditor calculatorEditor;
@NotNull
private CursorControlAdapter(@NotNull CalculatorEditor calculatorEditor) { private final CalculatorEditor calculatorEditor;
this.calculatorEditor = calculatorEditor;
} private CursorControlAdapter(@NotNull CalculatorEditor calculatorEditor) {
this.calculatorEditor = calculatorEditor;
@Override }
public void setCursorOnStart() {
this.calculatorEditor.setCursorOnStart(); @Override
} public void setCursorOnStart() {
this.calculatorEditor.setCursorOnStart();
@Override }
public void setCursorOnEnd() {
this.calculatorEditor.setCursorOnEnd(); @Override
} public void setCursorOnEnd() {
this.calculatorEditor.setCursorOnEnd();
@Override }
public void moveCursorLeft() {
this.calculatorEditor.moveCursorLeft(); @Override
} public void moveCursorLeft() {
this.calculatorEditor.moveCursorLeft();
@Override }
public void moveCursorRight() {
this.calculatorEditor.moveCursorRight(); @Override
} public void moveCursorRight() {
} this.calculatorEditor.moveCursorRight();
} }
}
}

View File

@ -1,16 +1,18 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** import java.io.Serializable;
* User: Solovyev_S
* Date: 21.09.12 /**
* Time: 11:48 * User: Solovyev_S
*/ * Date: 21.09.12
public interface CalculatorEditorViewState { * Time: 11:48
*/
@NotNull public interface CalculatorEditorViewState extends Serializable {
String getText();
@NotNull
int getSelection(); String getText();
}
int getSelection();
}

View File

@ -1,127 +1,154 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 20.09.12 * Date: 20.09.12
* Time: 16:40 * Time: 16:40
*/ */
public enum CalculatorEventType { public enum CalculatorEventType {
/* /*
********************************************************************** **********************************************************************
* *
* CALCULATION * CALCULATION
* org.solovyev.android.calculator.CalculatorEvaluationEventData * org.solovyev.android.calculator.CalculatorEvaluationEventData
* *
********************************************************************** **********************************************************************
*/ */
// @NotNull CalculatorEditorViewState // @NotNull CalculatorEditorViewState
manual_calculation_requested, manual_calculation_requested,
// @NotNull org.solovyev.android.calculator.CalculatorOutput // @NotNull org.solovyev.android.calculator.CalculatorOutput
calculation_result, calculation_result,
calculation_cancelled, calculation_cancelled,
// @NotNull org.solovyev.android.calculator.CalculatorFailure // @NotNull org.solovyev.android.calculator.CalculatorFailure
calculation_failed, calculation_failed,
/* /*
********************************************************************** **********************************************************************
* *
* CONVERSION * CONVERSION
* CalculatorConversionEventData * CalculatorConversionEventData
* *
********************************************************************** **********************************************************************
*/ */
conversion_started, conversion_started,
// @NotNull String conversion result // @NotNull String conversion result
conversion_result, conversion_result,
// @NotNull ConversionFailure // @NotNull ConversionFailure
conversion_failed, conversion_failed,
conversion_finished, conversion_finished,
/* /*
********************************************************************** **********************************************************************
* *
* EDITOR * EDITOR
* *
********************************************************************** **********************************************************************
*/ */
// @NotNull org.solovyev.android.calculator.CalculatorEditorChangeEventData // @NotNull org.solovyev.android.calculator.CalculatorEditorChangeEventData
editor_state_changed, editor_state_changed,
editor_state_changed_light,
// @NotNull CalculatorDisplayChangeEventData
display_state_changed, // @NotNull CalculatorDisplayChangeEventData
display_state_changed,
/*
********************************************************************** /*
* **********************************************************************
* ENGINE *
* * ENGINE
********************************************************************** *
*/ **********************************************************************
*/
engine_preferences_changed,
engine_preferences_changed,
/*
********************************************************************** /*
* **********************************************************************
* HISTORY *
* * HISTORY
********************************************************************** *
*/ **********************************************************************
*/
// @NotNull CalculatorHistoryState
history_state_added, // @NotNull CalculatorHistoryState
history_state_added,
// @NotNull CalculatorHistoryState
use_history_state, // @NotNull CalculatorHistoryState
use_history_state,
clear_history_requested,
clear_history_requested,
/*
********************************************************************** /*
* **********************************************************************
* MATH ENTITIES *
* * MATH ENTITIES
********************************************************************** *
*/ **********************************************************************
*/
// @NotNull IConstant
use_constant, // @NotNull IConstant
use_constant,
// @NotNull Function
use_function, // @NotNull Function
use_function,
// @NotNull Operator
use_operator, // @NotNull Operator
use_operator,
// @NotNull IConstant
constant_added, // @NotNull IConstant
constant_added,
// @NotNull Change<IConstant>
constant_changed, // @NotNull Change<IConstant>
constant_changed,
// @NotNull IConstant
constant_removed; // @NotNull IConstant
constant_removed,
public boolean isOfType(@NotNull CalculatorEventType... types) {
for (CalculatorEventType type : types) { /*
if ( this == type ) { **********************************************************************
return true; *
} * OTHER
} *
**********************************************************************
return false; */
} show_history,
show_history_detached,
}
show_functions,
show_functions_detached,
show_vars,
show_vars_detached,
open_app,
show_operators,
show_operators_detached,
show_settings,
show_settings_detached,
show_like_dialog;
public boolean isOfType(@NotNull CalculatorEventType... types) {
for (CalculatorEventType type : types) {
if ( this == type ) {
return true;
}
}
return false;
}
}

View File

@ -409,17 +409,17 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
case use_constant: case use_constant:
final IConstant constant = (IConstant)data; final IConstant constant = (IConstant)data;
CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(constant.getName()); CalculatorLocatorImpl.getInstance().getKeyboard().buttonPressed(constant.getName());
break; break;
case use_operator: case use_operator:
final Operator operator = (Operator)data; final Operator operator = (Operator)data;
CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(operator.getName()); CalculatorLocatorImpl.getInstance().getKeyboard().buttonPressed(operator.getName());
break; break;
case use_function: case use_function:
final Function function = (Function)data; final Function function = (Function)data;
CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(function.getName()); CalculatorLocatorImpl.getInstance().getKeyboard().buttonPressed(function.getName());
break; break;
} }

View File

@ -1,25 +1,25 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* User: serso * User: serso
* Date: 9/22/12 * Date: 9/22/12
* Time: 1:08 PM * Time: 1:08 PM
*/ */
public interface CalculatorKeyboard { public interface CalculatorKeyboard {
void digitButtonPressed(@Nullable String text); void buttonPressed(@Nullable String text);
void roundBracketsButtonPressed(); void roundBracketsButtonPressed();
void pasteButtonPressed(); void pasteButtonPressed();
void clearButtonPressed(); void clearButtonPressed();
void copyButtonPressed(); void copyButtonPressed();
void moveCursorLeft(); void moveCursorLeft();
void moveCursorRight(); void moveCursorRight();
} }

View File

@ -20,40 +20,57 @@ public class CalculatorKeyboardImpl implements CalculatorKeyboard {
} }
@Override @Override
public void digitButtonPressed(@Nullable final String text) { public void buttonPressed(@Nullable final String text) {
if (!StringUtils.isEmpty(text)) { if (!StringUtils.isEmpty(text)) {
assert text != null; assert text != null;
int cursorPositionOffset = 0; // process special buttons
final StringBuilder textToBeInserted = new StringBuilder(text); boolean processed = processSpecialButtons(text);
final MathType.Result mathType = MathType.getType(text, 0, false); if (!processed) {
switch (mathType.getMathType()) { int cursorPositionOffset = 0;
case function: final StringBuilder textToBeInserted = new StringBuilder(text);
textToBeInserted.append("()");
cursorPositionOffset = -1;
break;
case operator:
textToBeInserted.append("()");
cursorPositionOffset = -1;
break;
case comma:
textToBeInserted.append(" ");
break;
}
if (cursorPositionOffset == 0) { final MathType.Result mathType = MathType.getType(text, 0, false);
if (MathType.openGroupSymbols.contains(text)) { switch (mathType.getMathType()) {
cursorPositionOffset = -1; case function:
textToBeInserted.append("()");
cursorPositionOffset = -1;
break;
case operator:
textToBeInserted.append("()");
cursorPositionOffset = -1;
break;
case comma:
textToBeInserted.append(" ");
break;
} }
}
final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getEditor(); if (cursorPositionOffset == 0) {
editor.insert(textToBeInserted.toString(), cursorPositionOffset); if (MathType.openGroupSymbols.contains(text)) {
cursorPositionOffset = -1;
}
}
final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getEditor();
editor.insert(textToBeInserted.toString(), cursorPositionOffset);
}
} }
} }
private boolean processSpecialButtons(@NotNull String text) {
boolean result = false;
final CalculatorSpecialButton button = CalculatorSpecialButton.getByActionCode(text);
if ( button != null ) {
button.onClick(this);
result = true;
}
return result;
}
@Override @Override
public void roundBracketsButtonPressed() { public void roundBracketsButtonPressed() {
final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getEditor(); final CalculatorEditor editor = CalculatorLocatorImpl.getInstance().getEditor();

View File

@ -19,4 +19,6 @@ public interface CalculatorNotifier {
void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters); void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @NotNull List<Object> parameters);
void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters); void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters);
void showDebugMessage(@Nullable String tag, @NotNull String message);
} }

View File

@ -0,0 +1,155 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: serso
* Date: 10/20/12
* Time: 2:05 PM
*/
public enum CalculatorSpecialButton {
history("history") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history, null);
}
},
history_detached("history_detached") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_history_detached, null);
}
},
cursor_right("") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
keyboard.moveCursorRight();
}
},
cursor_left("") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
keyboard.moveCursorLeft();
}
},
settings("settings") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings, null);
}
},
settings_detached("settings_detached") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_settings_detached, null);
}
},
like("like") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_like_dialog, null);
}
},
erase("erase") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getEditor().erase();
}
},
paste("paste") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
keyboard.pasteButtonPressed();
}
},
copy("copy") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
keyboard.copyButtonPressed();
}
},
equals("=") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().evaluate();
}
},
clear("clear") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
keyboard.clearButtonPressed();
}
},
functions("functions") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions, null);
}
},
functions_detached("functions_detached") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_functions_detached, null);
}
},
open_app("open_app") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.open_app, null);
}
},
vars("vars") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars, null);
}
},
vars_detached("vars_detached") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_vars_detached, null);
}
},
operators("operators") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null);
}
},
operators_detached("operators_detached") {
@Override
public void onClick(@NotNull CalculatorKeyboard keyboard) {
CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators_detached, null);
}
};
@NotNull
private final String actionCode;
CalculatorSpecialButton(@NotNull String actionCode) {
this.actionCode = actionCode;
}
@NotNull
public String getActionCode() {
return actionCode;
}
@Nullable
public static CalculatorSpecialButton getByActionCode(@NotNull String actionCode) {
for (CalculatorSpecialButton button : values()) {
if (button.getActionCode().equals(actionCode)) {
return button;
}
}
return null;
}
public abstract void onClick(@NotNull CalculatorKeyboard keyboard);
}

View File

@ -25,4 +25,8 @@ public class DummyCalculatorNotifier implements CalculatorNotifier {
@Override @Override
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) { public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) {
} }
@Override
public void showDebugMessage(@Nullable String tag, @NotNull String message) {
}
} }

View File

@ -42,6 +42,7 @@ public class ListCalculatorEventContainer implements CalculatorEventContainer {
final CalculatorLogger logger = CalculatorLocatorImpl.getInstance().getLogger(); final CalculatorLogger logger = CalculatorLocatorImpl.getInstance().getLogger();
for (CalculatorEvent e : calculatorEvents) { for (CalculatorEvent e : calculatorEvents) {
CalculatorLocatorImpl.getInstance().getLogger().debug(TAG, "Event fired: " + e.getCalculatorEventType());
for (CalculatorEventListener listener : listeners) { for (CalculatorEventListener listener : listeners) {
/*long startTime = System.currentTimeMillis();*/ /*long startTime = System.currentTimeMillis();*/
listener.onCalculatorEvent(e.getCalculatorEventData(), e.getCalculatorEventType(), e.getData()); listener.onCalculatorEvent(e.getCalculatorEventData(), e.getCalculatorEventType(), e.getData());

View File

@ -0,0 +1,23 @@
package org.solovyev.android.calculator;
import jscl.math.Expression;
import org.junit.Test;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 10/20/12
* Time: 12:24 PM
*/
public class CalculatorDisplayViewStateImplTest {
@Test
public void testSerializable() throws Exception {
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newValidState(JsclOperation.numeric, null, "test", 3));
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newValidState(JsclOperation.numeric, Expression.valueOf("3"), "test", 3));
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newValidState(JsclOperation.simplify, Expression.valueOf("3+3"), "test", 3));
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newDefaultInstance());
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newErrorState(JsclOperation.numeric, "ertert"));
}
}

View File

@ -0,0 +1,21 @@
package org.solovyev.android.calculator;
import junit.framework.Assert;
import org.junit.Test;
/**
* User: serso
* Date: 10/20/12
* Time: 12:31 PM
*/
public class CalculatorEditorViewStateImplTest {
@Test
public void testSerialization() throws Exception {
CalculatorTestUtils.testSerialization(CalculatorEditorViewStateImpl.newDefaultInstance());
CalculatorEditorViewState out = CalculatorTestUtils.testSerialization(CalculatorEditorViewStateImpl.newInstance("treter", 2));
Assert.assertEquals(2, out.getSelection());
Assert.assertEquals("treter", out.getText());
}
}

View File

@ -8,6 +8,7 @@ import org.mockito.Mockito;
import org.solovyev.android.calculator.history.CalculatorHistory; import org.solovyev.android.calculator.history.CalculatorHistory;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import java.io.*;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -41,7 +42,7 @@ public class CalculatorTestUtils {
} }
public static void assertEval(@NotNull String expected, @NotNull String expression) { public static void assertEval(@NotNull String expected, @NotNull String expression) {
assertEval(expected, expression, JsclOperation.numeric); assertEval(expected, expression, JsclOperation.numeric);
} }
public static void assertEval(@NotNull String expected, @NotNull String expression, @NotNull JsclOperation operation) { public static void assertEval(@NotNull String expected, @NotNull String expression, @NotNull JsclOperation operation) {
@ -57,8 +58,8 @@ public class CalculatorTestUtils {
calculatorEventListener.setCalculatorEventData(calculator.evaluate(operation, expression)); calculatorEventListener.setCalculatorEventData(calculator.evaluate(operation, expression));
if (latch.await(TIMEOUT, TimeUnit.SECONDS)) { if (latch.await(TIMEOUT, TimeUnit.SECONDS)) {
Assert.assertNotNull(calculatorEventListener.getResult()); Assert.assertNotNull(calculatorEventListener.getResult());
Assert.assertEquals(expected, calculatorEventListener.getResult().getText()); Assert.assertEquals(expected, calculatorEventListener.getResult().getText());
} else { } else {
Assert.fail("Too long wait for: " + expression); Assert.fail("Too long wait for: " + expression);
} }
@ -74,7 +75,33 @@ public class CalculatorTestUtils {
assertError(expression, JsclOperation.numeric); assertError(expression, JsclOperation.numeric);
} }
private static final class TestCalculatorEventListener implements CalculatorEventListener { public static <S extends Serializable> S testSerialization(@NotNull S serializable) throws IOException, ClassNotFoundException {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(out);
oos.writeObject(serializable);
} finally {
if (oos != null) {
oos.close();
}
}
byte[] serialized = out.toByteArray();
Assert.assertTrue(serialized.length > 0);
final ObjectInputStream resultStream = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
final S result = (S) resultStream.readObject();
Assert.assertNotNull(result);
return result;
}
private static final class TestCalculatorEventListener implements CalculatorEventListener {
@Nullable @Nullable
private CalculatorEventData calculatorEventData; private CalculatorEventData calculatorEventData;
@ -95,7 +122,7 @@ public class CalculatorTestUtils {
@Override @Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
if ( this.calculatorEventData != null && calculatorEventData.isSameSequence(this.calculatorEventData) ) { if (this.calculatorEventData != null && calculatorEventData.isSameSequence(this.calculatorEventData)) {
if (calculatorEventType == CalculatorEventType.display_state_changed) { if (calculatorEventType == CalculatorEventType.display_state_changed) {
final CalculatorDisplayChangeEventData displayChange = (CalculatorDisplayChangeEventData) data; final CalculatorDisplayChangeEventData displayChange = (CalculatorDisplayChangeEventData) data;

View File

@ -1,57 +1,80 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" android:versionCode="102" android:versionName="1.4.3" package="org.solovyev.android.calculator"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" android:versionCode="102" android:versionName="1.4.3" package="org.solovyev.android.calculator">
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.android.vending.BILLING"/> <uses-permission android:name="com.android.vending.BILLING"/>
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="8"/> <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="8"/>
<application android:debuggable="false" android:hardwareAccelerated="false" android:icon="@drawable/icon" android:label="@string/c_app_name" android:name=".CalculatorApplication" android:theme="@style/metro_blue_theme"> <application android:debuggable="false" android:hardwareAccelerated="false" android:icon="@drawable/icon" android:label="@string/c_app_name" android:name=".CalculatorApplication" android:theme="@style/metro_blue_theme">
<activity android:label="@string/c_app_name" android:name=".CalculatorActivity" android:windowSoftInputMode="adjustPan"> <activity android:label="@string/c_app_name" android:name=".CalculatorActivity" android:windowSoftInputMode="adjustPan" android:clearTaskOnLaunch="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<!-- settings must use action bar icon--> <!-- settings must use action bar icon-->
<activity android:icon="@drawable/icon_action_bar" android:label="@string/c_app_settings" android:name=".CalculatorPreferencesActivity"/> <activity android:icon="@drawable/icon_action_bar" android:label="@string/c_app_settings" android:name=".CalculatorPreferencesActivity"/>
<activity android:label="@string/c_history" android:name=".history.CalculatorHistoryActivity"/> <activity android:label="@string/c_history" android:name=".history.CalculatorHistoryActivity"/>
<activity android:label="@string/c_about" android:name=".about.CalculatorAboutActivity"/> <activity android:label="@string/c_about" android:name=".about.CalculatorAboutActivity"/>
<activity android:label="@string/c_help" android:name=".help.CalculatorHelpActivity"/> <activity android:label="@string/c_help" android:name=".help.CalculatorHelpActivity"/>
<activity android:label="@string/c_functions" android:name=".math.edit.CalculatorFunctionsActivity"/> <activity android:label="@string/c_functions" android:name=".math.edit.CalculatorFunctionsActivity"/>
<activity android:label="@string/c_operators" android:name=".math.edit.CalculatorOperatorsActivity"/> <activity android:label="@string/c_operators" android:name=".math.edit.CalculatorOperatorsActivity"/>
<activity android:label="@string/c_vars_and_constants" android:name=".math.edit.CalculatorVarsActivity"/> <activity android:label="@string/c_vars_and_constants" android:name=".math.edit.CalculatorVarsActivity"/>
<activity android:label="@string/c_plot_graph" android:name=".plot.CalculatorPlotActivity"/> <activity android:label="@string/c_plot_graph" android:name=".plot.CalculatorPlotActivity"/>
<!-- settings must use action bar icon--> <activity android:name=".widget.CalculatorWidgetConfigurationActivity" android:theme="@style/metro_blue_theme">
<activity android:icon="@drawable/icon_action_bar" android:label="@string/c_settings" android:name=".plot.CalculatorPlotPreferenceActivity"/> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:name="com.google.ads.AdActivity"/> </intent-filter>
</activity>
<service android:name="net.robotmedia.billing.BillingService"/>
<receiver android:name="net.robotmedia.billing.BillingReceiver"> <!-- settings must use action bar icon-->
<intent-filter> <activity android:icon="@drawable/icon_action_bar" android:label="@string/c_settings" android:name=".plot.CalculatorPlotPreferenceActivity"/>
<action android:name="com.android.vending.billing.IN_APP_NOTIFY"/>
<action android:name="com.android.vending.billing.RESPONSE_CODE"/> <receiver
<action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED"/> android:icon="@drawable/icon"
</intent-filter> android:label="@string/c_app_name"
</receiver> android:name=".widget.CalculatorWidgetProvider">
<activity android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:launchMode="singleInstance" android:name="org.acra.CrashReportDialog" android:theme="@style/Theme.Sherlock.Dialog"/> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</application> <action android:name="org.solovyev.calculator.widget.EDITOR_STATE_CHANGED"/>
<action android:name="org.solovyev.calculator.widget.DISPLAY_STATE_CHANGED"/>
<action android:name="org.solovyev.calculator.widget.BUTTON_PRESSED"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/calculator_widget_info"/>
</receiver>
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:name="com.google.ads.AdActivity"/>
<service android:name="net.robotmedia.billing.BillingService"/>
<receiver android:name="net.robotmedia.billing.BillingReceiver">
<intent-filter>
<action android:name="com.android.vending.billing.IN_APP_NOTIFY"/>
<action android:name="com.android.vending.billing.RESPONSE_CODE"/>
<action android:name="com.android.vending.billing.PURCHASE_STATE_CHANGED"/>
</intent-filter>
</receiver>
<activity android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:launchMode="singleInstance" android:name="org.acra.CrashReportDialog" android:theme="@style/Theme.Sherlock.Dialog"/>
</application>
</manifest> </manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -1,24 +1,24 @@
# This file is automatically generated by Android Tools. # This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED! # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
# #
# This file must be checked in Version Control Systems. # This file must be checked in Version Control Systems.
# #
# To customize properties used by the Ant build system use, # To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your # "ant.properties", and override values to adapt the script to your
# project structure. # project structure.
# Project target. # Project target.
target=android-15 target=android-15
android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0 android.library.reference.1=gen-external-apklibs/org.solovyev.android_android-common-core_1.0.0
android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0 android.library.reference.2=gen-external-apklibs/org.solovyev.android_android-common-ads_1.0.0
android.library.reference.3=gen-external-apklibs/org.solovyev.android_billing_0.2 android.library.reference.3=gen-external-apklibs/org.solovyev.android_billing_0.2
android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-db_1.0.0 android.library.reference.4=gen-external-apklibs/org.solovyev.android_android-common-db_1.0.0
android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0 android.library.reference.5=gen-external-apklibs/org.solovyev.android_android-common-view_1.0.0
android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0 android.library.reference.6=gen-external-apklibs/org.solovyev.android_android-common-preferences_1.0.0
android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0 android.library.reference.7=gen-external-apklibs/org.solovyev.android_android-common-other_1.0.0
android.library.reference.8=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0 android.library.reference.8=gen-external-apklibs/org.solovyev.android_android-common-menu_1.0.0
android.library.reference.9=gen-external-apklibs/org.solovyev.android_android-common-sherlock_1.0.0 android.library.reference.9=gen-external-apklibs/org.solovyev.android_android-common-sherlock_1.0.0
android.library.reference.10=gen-external-apklibs/com.actionbarsherlock_library_4.1.0 android.library.reference.10=gen-external-apklibs/com.actionbarsherlock_library_4.1.0
android.library.reference.11=gen-external-apklibs/org.solovyev.android_android-common-list_1.0.0 android.library.reference.11=gen-external-apklibs/org.solovyev.android_android-common-list_1.0.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev. ~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
~ For more information, please, contact se.solovyev@gmail.com ~ For more information, please, contact se.solovyev@gmail.com
~ or visit http://se.solovyev.org ~ or visit http://se.solovyev.org
--> -->
<org.solovyev.android.view.ColorButton xmlns:a="http://schemas.android.com/apk/res/android" <org.solovyev.android.view.ColorButton xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator" xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/pasteButton" a:id="@+id/copyButton"
a:drawableTop="@drawable/kb_copy" a:drawableTop="@drawable/kb_copy"
style="?controlImageButtonStyle" style="?controlImageButtonStyle"
a:onClick="copyButtonClickHandler"/> a:onClick="copyButtonClickHandler"/>

View File

@ -8,7 +8,7 @@
<org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android" <org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator" xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/squareBracketsButton" a:id="@+id/periodButton"
a:text="." a:text="."
c:textUp="," c:textUp=","
c:directionTextScale="0.5" c:directionTextScale="0.5"

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev. ~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
~ For more information, please, contact se.solovyev@gmail.com ~ For more information, please, contact se.solovyev@gmail.com
~ or visit http://se.solovyev.org ~ or visit http://se.solovyev.org
--> -->
<org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android" <org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator" xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/leftButton" a:id="@+id/leftButton"
c:textUp="◀◀" c:textUp="◀◀"
a:text="◀" a:text="◀"
c:directionTextScale="0.5" c:directionTextScale="0.5"
style="?controlButtonStyle" style="?controlButtonStyle"
a:onClick="moveLeftButtonClickHandler"/> a:onClick="digitButtonClickHandler"/>

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
~ Copyright (c) 2009-2011. Created by serso aka se.solovyev. ~ Copyright (c) 2009-2011. Created by serso aka se.solovyev.
~ For more information, please, contact se.solovyev@gmail.com ~ For more information, please, contact se.solovyev@gmail.com
~ or visit http://se.solovyev.org ~ or visit http://se.solovyev.org
--> -->
<org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android" <org.solovyev.android.view.drag.DirectionDragButton xmlns:a="http://schemas.android.com/apk/res/android"
xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator" xmlns:c="http://schemas.android.com/apk/res/org.solovyev.android.calculator"
a:id="@+id/rightButton" a:id="@+id/rightButton"
c:textUp="▶▶" c:textUp="▶▶"
a:text="▶" a:text="▶"
c:directionTextScale="0.5" c:directionTextScale="0.5"
style="?controlButtonStyle" style="?controlButtonStyle"
a:onClick="moveRightButtonClickHandler"/> a:onClick="digitButtonClickHandler"/>

View File

@ -0,0 +1,13 @@
<?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"
a:id="@+id/appButton"
a:src="@drawable/kb_logo"
style="@style/widget_metro_control_image_button_style"
a:contentDescription="App"/>

View File

@ -0,0 +1,13 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/clearButton"
a:text="@string/c_clear"
a:textStyle="bold"
style="@style/widget_metro_control_button_style"/>

View File

@ -0,0 +1,13 @@
<?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"
a:id="@+id/copyButton"
a:src="@drawable/kb_copy"
style="@style/widget_metro_control_image_button_style"
a:contentDescription="Copy"/>

View File

@ -0,0 +1,16 @@
<?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
-->
<TextView
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/calculatorDisplay"
style="@style/widget_display_style"
a:textIsSelectable="true"
a:padding="@dimen/display_padding"
a:singleLine="false"
a:scrollbars="vertical"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/divisionButton"
a:text="/"
style="@style/widget_metro_blue_operation_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/periodButton"
a:text="."
style="@style/metro_digit_button_style"/>

View File

@ -0,0 +1,24 @@
<?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
-->
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/main_fragment_layout"
style="@style/default_fragment_layout_style"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:padding="@dimen/editor_padding">
<TextView
a:id="@+id/calculatorEditor"
style="@style/widget_editor_style"
a:textIsSelectable="true"
a:singleLine="false"
a:scrollbars="vertical"
a:hint="@string/c_calc_editor_hint"/>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/eightDigitButton"
a:text="8"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button
xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/equalsButton"
a:text="="
style="@style/widget_metro_control_button_style"/>

View File

@ -0,0 +1,13 @@
<?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"
a:id="@+id/eraseButton"
a:src="@drawable/kb_delete"
style="@style/widget_metro_control_image_button_style"
a:contentDescription="Erase"/>

View File

@ -0,0 +1,11 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/fiveDigitButton"
a:text="5"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,11 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/fourDigitButton"
a:text="4"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,13 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/functionsButton"
a:text="ƒ(x)"
a:textStyle="italic"
style="@style/widget_metro_control_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/historyButton"
a:text="@string/c_history_button"
style="@style/widget_metro_control_button_style"
a:textStyle="bold"/>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:orientation="vertical">
<LinearLayout a:layout_weight="1"
a:layout_width="match_parent"
a:layout_height="0dp">
<include layout="@layout/widget_seven_digit_button"/>
<include layout="@layout/widget_eight_digit_button"/>
<include layout="@layout/widget_nine_digit_button"/>
<include layout="@layout/widget_multiplication_button"/>
<include layout="@layout/widget_percent_button"/>
<include layout="@layout/widget_clear_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1"
a:layout_width="match_parent"
a:layout_height="0dp">
<include layout="@layout/widget_four_digit_button"/>
<include layout="@layout/widget_five_digit_button"/>
<include layout="@layout/widget_six_digit_button"/>
<include layout="@layout/widget_division_button"/>
<include layout="@layout/widget_power_button"/>
<include layout="@layout/widget_erase_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1"
a:layout_width="match_parent"
a:layout_height="0dp">
<include layout="@layout/widget_one_digit_button"/>
<include layout="@layout/widget_two_digit_button"/>
<include layout="@layout/widget_three_digit_button"/>
<include layout="@layout/widget_plus_button"/>
<include layout="@layout/widget_like_button"/>
<include layout="@layout/widget_copy_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1"
a:layout_width="match_parent"
a:layout_height="0dp">
<include layout="@layout/widget_round_brackets_button"/>
<include layout="@layout/widget_zero_digit_button"/>
<include layout="@layout/widget_dot_button"/>
<include layout="@layout/widget_subtraction_button"/>
<include layout="@layout/widget_settings_button"/>
<include layout="@layout/widget_paste_button"/>
</LinearLayout>
<LinearLayout a:layout_weight="1"
a:layout_width="match_parent"
a:layout_height="0dp">
<include layout="@layout/widget_left_button"/>
<include layout="@layout/widget_right_button"/>
<include layout="@layout/widget_vars_button"/>
<include layout="@layout/widget_functions_button"/>
<include layout="@layout/widget_app_button"/>
<include layout="@layout/widget_history_button"/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:orientation="vertical"
style="@style/widget_main_layout_style">
<include layout="@layout/widget_editor"
a:layout_weight="2"
a:layout_width="match_parent"
a:layout_height="0dp"/>
<LinearLayout a:layout_weight="1"
a:layout_width="match_parent"
a:layout_height="0dp">
<include layout="@layout/widget_equals_button"
a:layout_margin="@dimen/button_margin"
a:layout_weight="1"
a:layout_width="0dp"
a:layout_height="match_parent"/>
<include layout="@layout/widget_display"
a:layout_weight="5"
a:layout_width="0dp"
a:layout_height="wrap_content"/>
</LinearLayout>
<include layout="@layout/widget_keyboard"
a:layout_weight="5"
a:layout_width="match_parent"
a:layout_height="0dp"/>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/leftButton"
a:text="◀"
style="@style/widget_metro_control_button_style"/>

View File

@ -0,0 +1,13 @@
<?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"
a:id="@+id/likeButton"
a:src="@drawable/kb_facebook"
style="@style/widget_metro_control_image_button_style"
a:contentDescription="Like"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/multiplicationButton"
a:text="×"
style="@style/widget_metro_blue_operation_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/nineDigitButton"
a:text="9"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/oneDigitButton"
a:text="1"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,13 @@
<?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"
a:id="@+id/pasteButton"
a:src="@drawable/kb_paste"
style="@style/widget_metro_control_image_button_style"
a:contentDescription="Paste"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/percentButton"
a:text="%"
style="@style/widget_metro_blue_operation_button_style"/>

View File

@ -0,0 +1,11 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/plusButton"
a:text="+"
style="@style/widget_metro_blue_operation_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/powerButton"
a:text="^"
style="@style/widget_metro_blue_operation_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/rightButton"
a:text="▶"
style="@style/widget_metro_control_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/roundBracketsButton"
a:text="()"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,13 @@
<?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"
a:id="@+id/settingsButton"
a:src="@drawable/kb_settings"
style="@style/widget_metro_control_image_button_style"
a:contentDescription="Settings"/>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/sevenDigitButton"
a:text="7"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/sixDigitButton"
a:text="6"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,11 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/subtractionButton"
a:text="-"
style="@style/widget_metro_blue_operation_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/threeDigitButton"
a:text="3"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/twoDigitButton"
a:text="2"
style="@style/widget_metro_digit_button_style"/>

View File

@ -0,0 +1,13 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/varsButton"
a:text="π,…"
a:textStyle="italic"
style="@style/widget_metro_control_button_style"/>

View File

@ -0,0 +1,12 @@
<?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
-->
<Button xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/zeroDigitButton"
a:text="0"
style="@style/widget_metro_digit_button_style"/>

View File

@ -11,6 +11,7 @@
<color name="button_ce_text_color">#ffffffff</color> <color name="button_ce_text_color">#ffffffff</color>
<color name="default_text_color">#ffffffff</color> <color name="default_text_color">#ffffffff</color>
<color name="display_error_text_color">#ff393939</color> <color name="display_error_text_color">#ff393939</color>
<color name="widget_cursor_color">#ff707070</color>
<color name="selected_angle_unit_text_color">#ffffff99</color> <color name="selected_angle_unit_text_color">#ffffff99</color>
<color name="default_background">#ff000000</color> <color name="default_background">#ff000000</color>
<color name="pane_background">#ff1f1f1f</color> <color name="pane_background">#ff1f1f1f</color>

View File

@ -1,21 +1,25 @@
<resources> <resources>
<dimen name="text_size">20sp</dimen> <dimen name="text_size">20sp</dimen>
<dimen name="button_margin">0.5dp</dimen> <dimen name="button_margin">0.5dp</dimen>
<dimen name="display_margin_land">2.5dp</dimen> <dimen name="display_margin_land">2.5dp</dimen>
<dimen name="fragment_text_size">15sp</dimen> <dimen name="fragment_text_size">15sp</dimen>
<dimen name="fragment_title_text_size">20sp</dimen> <dimen name="fragment_title_text_size">20sp</dimen>
<dimen name="keyboard_button_text_size">30dp</dimen> <dimen name="keyboard_button_text_size">30dp</dimen>
<dimen name="button_text_size">20dp</dimen> <dimen name="button_text_size">20dp</dimen>
<dimen name="display_text_size">25sp</dimen> <dimen name="display_text_size">25sp</dimen>
<dimen name="editor_text_size">25sp</dimen> <dimen name="editor_text_size">25sp</dimen>
<dimen name="pane_margin">5dp</dimen> <dimen name="pane_margin">5dp</dimen>
<dimen name="pane_padding">5dp</dimen> <dimen name="pane_padding">5dp</dimen>
<dimen name="math_entity_text_size">20sp</dimen> <dimen name="math_entity_text_size">20sp</dimen>
<dimen name="math_entity_description_text_size">15sp</dimen> <dimen name="math_entity_description_text_size">15sp</dimen>
<!--only for not multipane--> <dimen name="widget_editor_text_size">25sp</dimen>
<dimen name="editor_padding">5dp</dimen> <dimen name="widget_keyboard_button_text_size">20dp</dimen>
<dimen name="display_padding">3dp</dimen> <dimen name="widget_display_text_size">25sp</dimen>
<!--only for not multipane-->
<dimen name="editor_padding">5dp</dimen>
<dimen name="display_padding">3dp</dimen>
</resources> </resources>

View File

@ -58,6 +58,14 @@
<item name="android:textSize">@dimen/display_text_size</item> <item name="android:textSize">@dimen/display_text_size</item>
</style> </style>
<style name="widget_editor_style" parent="editor_style">
<item name="android:textSize">@dimen/widget_editor_text_size</item>
</style>
<style name="widget_display_style" parent="display_style">
<item name="android:textSize">@dimen/widget_display_text_size</item>
</style>
<style name="about_style" parent="default_text"> <style name="about_style" parent="default_text">
<item name="android:gravity">center</item> <item name="android:gravity">center</item>
<item name="android:layout_width">fill_parent</item> <item name="android:layout_width">fill_parent</item>

View File

@ -80,6 +80,10 @@
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
</style> </style>
<style name="widget_main_layout_style" parent="default_main_layout_style">
<item name="android:padding">1dp</item>
</style>
<style name="default_actionbar_style" parent="@style/Widget.Sherlock.ActionBar"> <style name="default_actionbar_style" parent="@style/Widget.Sherlock.ActionBar">
<item name="background">@drawable/default_abs__ab_transparent_dark_holo</item> <item name="background">@drawable/default_abs__ab_transparent_dark_holo</item>
<item name="android:background">@drawable/default_abs__ab_transparent_dark_holo</item> <item name="android:background">@drawable/default_abs__ab_transparent_dark_holo</item>

View File

@ -4,18 +4,34 @@
<item name="android:background">@drawable/metro_button_dark</item> <item name="android:background">@drawable/metro_button_dark</item>
</style> </style>
<style name="widget_metro_digit_button_style" parent="metro_digit_button_style">
<item name="android:textSize">@dimen/widget_keyboard_button_text_size</item>
</style>
<style name="metro_control_button_style" parent="metro_digit_button_style"> <style name="metro_control_button_style" parent="metro_digit_button_style">
<item name="android:background">@drawable/metro_button_light</item> <item name="android:background">@drawable/metro_button_light</item>
</style> </style>
<style name="widget_metro_control_button_style" parent="metro_control_button_style">
<item name="android:textSize">@dimen/widget_keyboard_button_text_size</item>
</style>
<style name="metro_blue_operation_button_style" parent="metro_digit_button_style"> <style name="metro_blue_operation_button_style" parent="metro_digit_button_style">
<item name="android:background">@drawable/metro_blue_button</item> <item name="android:background">@drawable/metro_blue_button</item>
</style> </style>
<style name="widget_metro_blue_operation_button_style" parent="metro_blue_operation_button_style">
<item name="android:textSize">@dimen/widget_keyboard_button_text_size</item>
</style>
<style name="metro_control_image_button_style" parent="metro_control_button_style"> <style name="metro_control_image_button_style" parent="metro_control_button_style">
<item name="android:padding">6dp</item> <item name="android:padding">6dp</item>
</style> </style>
<style name="widget_metro_control_image_button_style" parent="metro_control_image_button_style">
<item name="android:scaleType">center</item>
</style>
<style name="metro_blue_fragment_list_view_item_style" parent="default_fragment_list_view_item_style"> <style name="metro_blue_fragment_list_view_item_style" parent="default_fragment_list_view_item_style">
<item name="background">@drawable/metro_blue_list_item</item> <item name="background">@drawable/metro_blue_list_item</item>
<item name="android:background">@drawable/metro_blue_list_item</item> <item name="android:background">@drawable/metro_blue_list_item</item>

View File

@ -1,34 +1,17 @@
<resources> <resources>
<style name="metro_digit_button_style" parent="keyboard_button_style">
<item name="android:background">@drawable/metro_button_dark</item>
</style>
<style name="metro_control_button_style" parent="metro_digit_button_style">
<item name="android:background">@drawable/metro_button_light</item>
</style>
<style name="metro_green_operation_button_style" parent="metro_digit_button_style"> <style name="metro_green_operation_button_style" parent="metro_digit_button_style">
<item name="android:background">@drawable/metro_button_green</item> <item name="android:background">@drawable/metro_button_green</item>
</style> </style>
<style name="metro_control_image_button_style" parent="metro_control_button_style">
<item name="android:padding">6dp</item>
</style>
<style name="metro_green_fragment_list_view_item_style" parent="default_fragment_list_view_item_style"> <style name="metro_green_fragment_list_view_item_style" parent="default_fragment_list_view_item_style">
<item name="background">@drawable/metro_green_list_item</item> <item name="background">@drawable/metro_green_list_item</item>
<item name="android:background">@drawable/metro_green_list_item</item> <item name="android:background">@drawable/metro_green_list_item</item>
</style> </style>
<style name="metro_green_theme" parent="default_theme"> <style name="metro_green_theme" parent="metro_blue_theme">
<item name="digitButtonStyle">@style/metro_digit_button_style</item>
<item name="controlButtonStyle">@style/metro_control_button_style</item>
<item name="controlImageButtonStyle">@style/metro_control_image_button_style</item>
<item name="operationButtonStyle">@style/metro_green_operation_button_style</item> <item name="operationButtonStyle">@style/metro_green_operation_button_style</item>
<item name="fragmentListViewItemStyle">@style/metro_green_fragment_list_view_item_style</item> <item name="fragmentListViewItemStyle">@style/metro_green_fragment_list_view_item_style</item>
</style> </style>
</resources> </resources>

View File

@ -1,34 +1,18 @@
<resources> <resources>
<style name="metro_digit_button_style" parent="keyboard_button_style">
<item name="android:background">@drawable/metro_button_dark</item>
</style>
<style name="metro_control_button_style" parent="metro_digit_button_style">
<item name="android:background">@drawable/metro_button_light</item>
</style>
<style name="metro_purple_operation_button_style" parent="metro_digit_button_style"> <style name="metro_purple_operation_button_style" parent="metro_digit_button_style">
<item name="android:background">@drawable/metro_button_purple</item> <item name="android:background">@drawable/metro_button_purple</item>
</style> </style>
<style name="metro_control_image_button_style" parent="metro_control_button_style">
<item name="android:padding">6dp</item>
</style>
<style name="metro_purple_fragment_list_view_item_style" parent="default_fragment_list_view_item_style"> <style name="metro_purple_fragment_list_view_item_style" parent="default_fragment_list_view_item_style">
<item name="background">@drawable/metro_purple_list_item</item> <item name="background">@drawable/metro_purple_list_item</item>
<item name="android:background">@drawable/metro_purple_list_item</item> <item name="android:background">@drawable/metro_purple_list_item</item>
</style> </style>
<style name="metro_purple_theme" parent="default_theme"> <style name="metro_purple_theme" parent="metro_blue_theme">
<item name="digitButtonStyle">@style/metro_digit_button_style</item>
<item name="controlButtonStyle">@style/metro_control_button_style</item>
<item name="controlImageButtonStyle">@style/metro_control_image_button_style</item>
<item name="operationButtonStyle">@style/metro_purple_operation_button_style</item> <item name="operationButtonStyle">@style/metro_purple_operation_button_style</item>
<item name="fragmentListViewItemStyle">@style/metro_purple_fragment_list_view_item_style</item> <item name="fragmentListViewItemStyle">@style/metro_purple_fragment_list_view_item_style</item>
</style> </style>
</resources> </resources>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:a="http://schemas.android.com/apk/res/android"
a:minWidth="180dp"
a:minHeight="220dp"
a:initialLayout="@layout/widget_layout"
a:previewImage="@drawable/widget_preview"
a:resizeMode="horizontal|vertical">
</appwidget-provider>

View File

@ -1,35 +1,40 @@
package org.solovyev.android; package org.solovyev.android;
import android.support.v4.app.DialogFragment; import android.os.Looper;
import android.support.v4.app.Fragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentManager;
import org.jetbrains.annotations.NotNull; import android.support.v4.app.FragmentTransaction;
import org.jetbrains.annotations.NotNull;
/**
* User: Solovyev_S /**
* Date: 03.10.12 * User: Solovyev_S
* Time: 10:48 * Date: 03.10.12
*/ * Time: 10:48
public final class AndroidUtils2 { */
public final class AndroidUtils2 {
private AndroidUtils2() {
throw new AssertionError(); private AndroidUtils2() {
} throw new AssertionError();
}
public static void showDialog(@NotNull DialogFragment dialogFragment,
@NotNull String fragmentTag, public static void showDialog(@NotNull DialogFragment dialogFragment,
@NotNull FragmentManager fm) { @NotNull String fragmentTag,
final FragmentTransaction ft = fm.beginTransaction(); @NotNull FragmentManager fm) {
final FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(fragmentTag);
if (prev != null) { Fragment prev = fm.findFragmentByTag(fragmentTag);
ft.remove(prev); if (prev != null) {
} ft.remove(prev);
ft.addToBackStack(null); }
ft.addToBackStack(null);
// Create and show the dialog.
dialogFragment.show(ft, fragmentTag); // Create and show the dialog.
dialogFragment.show(ft, fragmentTag);
}
} }
public static boolean isUiThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
}

View File

@ -1,238 +1,238 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Activity; import android.app.Activity;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Vibrator; import android.os.Vibrator;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.view.AngleUnitsButton; import org.solovyev.android.calculator.view.AngleUnitsButton;
import org.solovyev.android.calculator.view.NumeralBasesButton; import org.solovyev.android.calculator.view.NumeralBasesButton;
import org.solovyev.android.calculator.view.OnDragListenerVibrator; import org.solovyev.android.calculator.view.OnDragListenerVibrator;
import org.solovyev.android.history.HistoryDragProcessor; import org.solovyev.android.history.HistoryDragProcessor;
import org.solovyev.android.view.drag.*; import org.solovyev.android.view.drag.*;
import org.solovyev.common.Announcer; import org.solovyev.common.Announcer;
import org.solovyev.common.math.Point2d; import org.solovyev.common.math.Point2d;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* User: serso * User: serso
* Date: 9/28/12 * Date: 9/28/12
* Time: 12:12 AM * Time: 12:12 AM
*/ */
public abstract class AbstractCalculatorHelper implements SharedPreferences.OnSharedPreferenceChangeListener { public abstract class AbstractCalculatorHelper implements SharedPreferences.OnSharedPreferenceChangeListener {
@NotNull @NotNull
private CalculatorPreferences.Gui.Layout layout; private CalculatorPreferences.Gui.Layout layout;
@NotNull @NotNull
private CalculatorPreferences.Gui.Theme theme; private CalculatorPreferences.Gui.Theme theme;
@Nullable @Nullable
private Vibrator vibrator; private Vibrator vibrator;
@NotNull @NotNull
private final Announcer<DragPreferencesChangeListener> dpclRegister = new Announcer<DragPreferencesChangeListener>(DragPreferencesChangeListener.class); private final Announcer<DragPreferencesChangeListener> dpclRegister = new Announcer<DragPreferencesChangeListener>(DragPreferencesChangeListener.class);
@NotNull @NotNull
private String logTag = "CalculatorActivity"; private String logTag = "CalculatorActivity";
protected AbstractCalculatorHelper() { protected AbstractCalculatorHelper() {
} }
protected AbstractCalculatorHelper(@NotNull String logTag) { protected AbstractCalculatorHelper(@NotNull String logTag) {
this.logTag = logTag; this.logTag = logTag;
} }
protected void onCreate(@NotNull Activity activity) { protected void onCreate(@NotNull Activity activity) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
vibrator = (Vibrator) activity.getSystemService(Activity.VIBRATOR_SERVICE); vibrator = (Vibrator) activity.getSystemService(Activity.VIBRATOR_SERVICE);
layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences); layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences);
theme = CalculatorPreferences.Gui.theme.getPreferenceNoError(preferences); theme = CalculatorPreferences.Gui.theme.getPreferenceNoError(preferences);
preferences.registerOnSharedPreferenceChangeListener(this); preferences.registerOnSharedPreferenceChangeListener(this);
} }
public void logDebug(@NotNull String message) { public void logDebug(@NotNull String message) {
Log.d(logTag, message); Log.d(logTag, message);
} }
public void logError(@NotNull String message) { public void logError(@NotNull String message) {
Log.e(logTag, message); Log.e(logTag, message);
} }
public void processButtons(@NotNull final Activity activity, @NotNull View root) { public void processButtons(@NotNull final Activity activity, @NotNull View root) {
dpclRegister.clear(); dpclRegister.clear();
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, activity); final SimpleOnDragListener.Preferences dragPreferences = SimpleOnDragListener.getPreferences(preferences, activity);
setOnDragListeners(root, dragPreferences, preferences); setOnDragListeners(root, dragPreferences, preferences);
final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor<CalculatorHistoryState>(getCalculator()), dragPreferences), vibrator, preferences); final OnDragListener historyOnDragListener = new OnDragListenerVibrator(newOnDragListener(new HistoryDragProcessor<CalculatorHistoryState>(getCalculator()), dragPreferences), vibrator, preferences);
final DragButton historyButton = getButton(root, R.id.historyButton); final DragButton historyButton = getButton(root, R.id.historyButton);
if (historyButton != null) { if (historyButton != null) {
historyButton.setOnDragListener(historyOnDragListener); historyButton.setOnDragListener(historyOnDragListener);
} }
final DragButton subtractionButton = getButton(root, R.id.subtractionButton); final DragButton subtractionButton = getButton(root, R.id.subtractionButton);
if (subtractionButton != null) { if (subtractionButton != null) {
subtractionButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() { subtractionButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new SimpleOnDragListener.DragProcessor() {
@Override @Override
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
if (dragDirection == DragDirection.down) { if (dragDirection == DragDirection.down) {
CalculatorActivity.operatorsButtonClickHandler(activity); CalculatorLocatorImpl.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_operators, null);
return true; return true;
} }
return false; return false;
} }
}, dragPreferences), vibrator, preferences)); }, dragPreferences), vibrator, preferences));
} }
final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(), dragPreferences), vibrator, preferences); final OnDragListener toPositionOnDragListener = new OnDragListenerVibrator(new SimpleOnDragListener(new CursorDragProcessor(), dragPreferences), vibrator, preferences);
final DragButton rightButton = getButton(root, R.id.rightButton); final DragButton rightButton = getButton(root, R.id.rightButton);
if (rightButton != null) { if (rightButton != null) {
rightButton.setOnDragListener(toPositionOnDragListener); rightButton.setOnDragListener(toPositionOnDragListener);
} }
final DragButton leftButton = getButton(root, R.id.leftButton); final DragButton leftButton = getButton(root, R.id.leftButton);
if (leftButton != null) { if (leftButton != null) {
leftButton.setOnDragListener(toPositionOnDragListener); leftButton.setOnDragListener(toPositionOnDragListener);
} }
final DragButton equalsButton = getButton(root, R.id.equalsButton); final DragButton equalsButton = getButton(root, R.id.equalsButton);
if (equalsButton != null) { if (equalsButton != null) {
equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(), dragPreferences), vibrator, preferences)); equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(), dragPreferences), vibrator, preferences));
} }
final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) getButton(root, R.id.sixDigitButton); final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) getButton(root, R.id.sixDigitButton);
if (angleUnitsButton != null) { if (angleUnitsButton != null) {
angleUnitsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.AngleUnitsChanger(activity), dragPreferences), vibrator, preferences)); angleUnitsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.AngleUnitsChanger(activity), dragPreferences), vibrator, preferences));
} }
final NumeralBasesButton clearButton = (NumeralBasesButton) getButton(root, R.id.clearButton); final NumeralBasesButton clearButton = (NumeralBasesButton) getButton(root, R.id.clearButton);
if (clearButton != null) { if (clearButton != null) {
clearButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.NumeralBasesChanger(activity), dragPreferences), vibrator, preferences)); clearButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.NumeralBasesChanger(activity), dragPreferences), vibrator, preferences));
} }
final DragButton varsButton = getButton(root, R.id.varsButton); final DragButton varsButton = getButton(root, R.id.varsButton);
if (varsButton != null) { if (varsButton != null) {
varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.VarsDragProcessor(activity), dragPreferences), vibrator, preferences)); varsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.VarsDragProcessor(activity), dragPreferences), vibrator, preferences));
} }
final DragButton roundBracketsButton = getButton(root, R.id.roundBracketsButton); final DragButton roundBracketsButton = getButton(root, R.id.roundBracketsButton);
if (roundBracketsButton != null) { if (roundBracketsButton != null) {
roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences)); roundBracketsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new CalculatorButtons.RoundBracketsDragProcessor(), dragPreferences), vibrator, preferences));
} }
if (layout == CalculatorPreferences.Gui.Layout.simple) { if (layout == CalculatorPreferences.Gui.Layout.simple) {
toggleButtonDirectionText(root, R.id.oneDigitButton, false, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.oneDigitButton, false, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.twoDigitButton, false, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.twoDigitButton, false, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.threeDigitButton, false, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.threeDigitButton, false, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.sixDigitButton, false, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.sixDigitButton, false, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.sevenDigitButton, false, DragDirection.left, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.sevenDigitButton, false, DragDirection.left, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.eightDigitButton, false, DragDirection.left, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.eightDigitButton, false, DragDirection.left, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.clearButton, false, DragDirection.left, DragDirection.up, DragDirection.down); toggleButtonDirectionText(root, R.id.clearButton, false, DragDirection.left, DragDirection.up, DragDirection.down);
toggleButtonDirectionText(root, R.id.fourDigitButton, false, DragDirection.down); toggleButtonDirectionText(root, R.id.fourDigitButton, false, DragDirection.down);
toggleButtonDirectionText(root, R.id.fiveDigitButton, false, DragDirection.down); toggleButtonDirectionText(root, R.id.fiveDigitButton, false, DragDirection.down);
toggleButtonDirectionText(root, R.id.nineDigitButton, false, DragDirection.left); toggleButtonDirectionText(root, R.id.nineDigitButton, false, DragDirection.left);
toggleButtonDirectionText(root, R.id.multiplicationButton, false, DragDirection.left); toggleButtonDirectionText(root, R.id.multiplicationButton, false, DragDirection.left);
toggleButtonDirectionText(root, R.id.plusButton, false, DragDirection.down, DragDirection.up); toggleButtonDirectionText(root, R.id.plusButton, false, DragDirection.down, DragDirection.up);
} }
CalculatorButtons.processButtons(true, theme, root); CalculatorButtons.processButtons(true, theme, root);
CalculatorButtons.toggleEqualsButton(preferences, activity); CalculatorButtons.toggleEqualsButton(preferences, activity);
CalculatorButtons.initMultiplicationButton(root); CalculatorButtons.initMultiplicationButton(root);
NumeralBaseButtons.toggleNumericDigits(activity, preferences); NumeralBaseButtons.toggleNumericDigits(activity, preferences);
} }
private void toggleButtonDirectionText(@NotNull View root, int id, boolean showDirectionText, @NotNull DragDirection... dragDirections) { private void toggleButtonDirectionText(@NotNull View root, int id, boolean showDirectionText, @NotNull DragDirection... dragDirections) {
final View v = getButton(root, id); final View v = getButton(root, id);
if (v instanceof DirectionDragButton ) { if (v instanceof DirectionDragButton ) {
final DirectionDragButton button = (DirectionDragButton)v; final DirectionDragButton button = (DirectionDragButton)v;
for (DragDirection dragDirection : dragDirections) { for (DragDirection dragDirection : dragDirections) {
button.showDirectionText(showDirectionText, dragDirection); button.showDirectionText(showDirectionText, dragDirection);
} }
} }
} }
@NotNull @NotNull
private Calculator getCalculator() { private Calculator getCalculator() {
return CalculatorLocatorImpl.getInstance().getCalculator(); return CalculatorLocatorImpl.getInstance().getCalculator();
} }
private void setOnDragListeners(@NotNull View root, @NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) { private void setOnDragListeners(@NotNull View root, @NotNull SimpleOnDragListener.Preferences dragPreferences, @NotNull SharedPreferences preferences) {
final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(getKeyboard()), dragPreferences), vibrator, preferences); final OnDragListener onDragListener = new OnDragListenerVibrator(newOnDragListener(new DigitButtonDragProcessor(getKeyboard()), dragPreferences), vibrator, preferences);
final List<Integer> dragButtonIds = new ArrayList<Integer>(); final List<Integer> dragButtonIds = new ArrayList<Integer>();
for (Field field : R.id.class.getDeclaredFields()) { for (Field field : R.id.class.getDeclaredFields()) {
int modifiers = field.getModifiers(); int modifiers = field.getModifiers();
if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) { if (Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers)) {
try { try {
int viewId = field.getInt(R.id.class); int viewId = field.getInt(R.id.class);
final View view = root.findViewById(viewId); final View view = root.findViewById(viewId);
if (view instanceof DragButton) { if (view instanceof DragButton) {
dragButtonIds.add(viewId); dragButtonIds.add(viewId);
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
Log.e(R.id.class.getName(), e.getMessage()); Log.e(R.id.class.getName(), e.getMessage());
} }
} }
} }
for (Integer dragButtonId : dragButtonIds) { for (Integer dragButtonId : dragButtonIds) {
final DragButton button = getButton(root, dragButtonId); final DragButton button = getButton(root, dragButtonId);
if (button != null) { if (button != null) {
button.setOnDragListener(onDragListener); button.setOnDragListener(onDragListener);
} }
} }
} }
@NotNull @NotNull
private CalculatorKeyboard getKeyboard() { private CalculatorKeyboard getKeyboard() {
return CalculatorLocatorImpl.getInstance().getKeyboard(); return CalculatorLocatorImpl.getInstance().getKeyboard();
} }
@Nullable @Nullable
private <T extends DragButton> T getButton(@NotNull View root, int buttonId) { private <T extends DragButton> T getButton(@NotNull View root, int buttonId) {
return (T) root.findViewById(buttonId); return (T) root.findViewById(buttonId);
} }
@NotNull @NotNull
private SimpleOnDragListener newOnDragListener(@NotNull SimpleOnDragListener.DragProcessor dragProcessor, private SimpleOnDragListener newOnDragListener(@NotNull SimpleOnDragListener.DragProcessor dragProcessor,
@NotNull SimpleOnDragListener.Preferences dragPreferences) { @NotNull SimpleOnDragListener.Preferences dragPreferences) {
final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences); final SimpleOnDragListener onDragListener = new SimpleOnDragListener(dragProcessor, dragPreferences);
dpclRegister.addListener(onDragListener); dpclRegister.addListener(onDragListener);
return onDragListener; return onDragListener;
} }
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key != null && key.startsWith("org.solovyev.android.calculator.DragButtonCalibrationActivity")) { if (key != null && key.startsWith("org.solovyev.android.calculator.DragButtonCalibrationActivity")) {
dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, CalculatorApplication.getInstance())); dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, CalculatorApplication.getInstance()));
} }
} }
public void onDestroy(@NotNull Activity activity) { public void onDestroy(@NotNull Activity activity) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
preferences.unregisterOnSharedPreferenceChangeListener(this); preferences.unregisterOnSharedPreferenceChangeListener(this);
} }
} }

View File

@ -21,11 +21,15 @@ import java.util.List;
* Date: 9/22/12 * Date: 9/22/12
* Time: 5:42 PM * Time: 5:42 PM
*/ */
public class AndroidCalculator implements Calculator { public class AndroidCalculator implements Calculator, CalculatorEventListener {
@NotNull @NotNull
private final Calculator calculator = new CalculatorImpl(); private final Calculator calculator = new CalculatorImpl();
public AndroidCalculator() {
this.calculator.addCalculatorEventListener(this);
}
public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) { public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
@ -170,4 +174,45 @@ public class AndroidCalculator implements Calculator {
calculator.simplify(); calculator.simplify();
} }
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) {
case show_history:
CalculatorActivityLauncher.showHistory(CalculatorApplication.getInstance());
break;
case show_history_detached:
CalculatorActivityLauncher.showHistory(CalculatorApplication.getInstance(), true);
break;
case show_functions:
CalculatorActivityLauncher.showFunctions(CalculatorApplication.getInstance());
break;
case show_functions_detached:
CalculatorActivityLauncher.showFunctions(CalculatorApplication.getInstance(), true);
break;
case show_operators:
CalculatorActivityLauncher.showOperators(CalculatorApplication.getInstance());
break;
case show_operators_detached:
CalculatorActivityLauncher.showOperators(CalculatorApplication.getInstance(), true);
break;
case show_vars:
CalculatorActivityLauncher.showVars(CalculatorApplication.getInstance());
break;
case show_vars_detached:
CalculatorActivityLauncher.showVars(CalculatorApplication.getInstance(), true);
break;
case show_settings:
CalculatorActivityLauncher.showSettings(CalculatorApplication.getInstance());
break;
case show_settings_detached:
CalculatorActivityLauncher.showSettings(CalculatorApplication.getInstance(), true);
break;
case show_like_dialog:
CalculatorActivityLauncher.likeButtonPressed(CalculatorApplication.getInstance());
break;
case open_app:
CalculatorActivityLauncher.openApp(CalculatorApplication.getInstance());
break;
}
}
} }

View File

@ -47,9 +47,8 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe
private volatile boolean viewStateChange = false; private volatile boolean viewStateChange = false;
// NOTE: static because super constructor calls some overridden methods (like onSelectionChanged and current lock is not yet created) @Nullable
@NotNull private final Object viewLock = new Object();
private static final Object viewLock = new Object();
@NotNull @NotNull
private final Handler uiHandler = new Handler(); private final Handler uiHandler = new Handler();
@ -154,45 +153,51 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe
@Override @Override
public void setState(@NotNull final CalculatorEditorViewState viewState) { public void setState(@NotNull final CalculatorEditorViewState viewState) {
synchronized (viewLock) { if (viewLock != null) {
synchronized (viewLock) {
final CharSequence text = prepareText(viewState.getText(), highlightText); final CharSequence text = prepareText(viewState.getText(), highlightText);
uiHandler.post(new Runnable() { uiHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this; final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
synchronized (viewLock) { synchronized (viewLock) {
try { try {
editorView.viewStateChange = true; editorView.viewStateChange = true;
editorView.viewState = viewState; editorView.viewState = viewState;
editorView.setText(text, BufferType.EDITABLE); editorView.setText(text, BufferType.EDITABLE);
editorView.setSelection(viewState.getSelection()); editorView.setSelection(viewState.getSelection());
} finally { } finally {
editorView.viewStateChange = false; editorView.viewStateChange = false;
}
} }
} }
} });
}); }
} }
} }
@Override @Override
protected void onSelectionChanged(int selStart, int selEnd) { protected void onSelectionChanged(int selStart, int selEnd) {
synchronized (viewLock) { if (viewLock != null) {
if (!viewStateChange) { synchronized (viewLock) {
// external text change => need to notify editor if (!viewStateChange) {
super.onSelectionChanged(selStart, selEnd); // external text change => need to notify editor
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart); super.onSelectionChanged(selStart, selEnd);
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
}
} }
} }
} }
public void handleTextChange(Editable s) { public void handleTextChange(Editable s) {
synchronized (viewLock) { if (viewLock != null) {
if (!viewStateChange) { synchronized (viewLock) {
// external text change => need to notify editor if (!viewStateChange) {
CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s)); // external text change => need to notify editor
CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s));
}
} }
} }
} }

View File

@ -1,9 +1,11 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Application; import android.app.Application;
import android.os.Handler;
import android.widget.Toast; import android.widget.Toast;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils2;
import org.solovyev.android.msg.AndroidMessage; import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType; import org.solovyev.common.msg.MessageType;
@ -20,13 +22,18 @@ public class AndroidCalculatorNotifier implements CalculatorNotifier {
@NotNull @NotNull
private final Application application; private final Application application;
@NotNull
private final Handler uiHandler = new Handler();
public AndroidCalculatorNotifier(@NotNull Application application) { public AndroidCalculatorNotifier(@NotNull Application application) {
assert AndroidUtils2.isUiThread();
this.application = application; this.application = application;
} }
@Override @Override
public void showMessage(@NotNull Message message) { public void showMessage(@NotNull Message message) {
Toast.makeText(application, message.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); showMessageInUiThread(message.getLocalizedMessage());
} }
@Override @Override
@ -38,4 +45,25 @@ public class AndroidCalculatorNotifier implements CalculatorNotifier {
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) { public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... parameters) {
showMessage(new AndroidMessage(messageCode, messageType, application, parameters)); showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
} }
@Override
public void showDebugMessage(@Nullable final String tag, @NotNull final String message) {
/*if (AndroidUtils.isDebuggable(application)) {
showMessageInUiThread(tag == null ? message : tag + ": " + message);
}*/
}
private void showMessageInUiThread(@NotNull final String message) {
if (AndroidUtils2.isUiThread()) {
Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
} else {
uiHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(application,message, Toast.LENGTH_SHORT).show();
}
});
}
}
} }

View File

@ -5,7 +5,6 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -18,6 +17,7 @@ import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -167,7 +167,7 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void equalsButtonClickHandler(@NotNull View v) { public void equalsButtonClickHandler(@NotNull View v) {
getCalculator().evaluate(); buttonPressed(CalculatorSpecialButton.equals);
} }
@Override @Override
@ -241,12 +241,12 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void historyButtonClickHandler(@NotNull View v) { public void historyButtonClickHandler(@NotNull View v) {
CalculatorActivityLauncher.showHistory(this); buttonPressed(CalculatorSpecialButton.history);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void eraseButtonClickHandler(@NotNull View v) { public void eraseButtonClickHandler(@NotNull View v) {
CalculatorLocatorImpl.getInstance().getEditor().erase(); buttonPressed(CalculatorSpecialButton.erase);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
@ -254,24 +254,14 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
throw new UnsupportedOperationException("Not implemented yet!"); throw new UnsupportedOperationException("Not implemented yet!");
} }
@SuppressWarnings({"UnusedDeclaration"})
public void moveLeftButtonClickHandler(@NotNull View v) {
getKeyboard().moveCursorLeft();
}
@SuppressWarnings({"UnusedDeclaration"})
public void moveRightButtonClickHandler(@NotNull View v) {
getKeyboard().moveCursorRight();
}
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void pasteButtonClickHandler(@NotNull View v) { public void pasteButtonClickHandler(@NotNull View v) {
getKeyboard().pasteButtonPressed(); buttonPressed(CalculatorSpecialButton.paste);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void copyButtonClickHandler(@NotNull View v) { public void copyButtonClickHandler(@NotNull View v) {
getKeyboard().copyButtonPressed(); buttonPressed(CalculatorSpecialButton.copy);
} }
@NotNull @NotNull
@ -281,39 +271,52 @@ public class CalculatorActivity extends SherlockFragmentActivity implements Shar
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void clearButtonClickHandler(@NotNull View v) { public void clearButtonClickHandler(@NotNull View v) {
getKeyboard().clearButtonPressed(); buttonPressed(CalculatorSpecialButton.clear);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void digitButtonClickHandler(@NotNull View v) { public void digitButtonClickHandler(@NotNull View v) {
Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed()); Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed());
if (((ColorButton) v).isShowText()) {
getKeyboard().digitButtonPressed(((ColorButton) v).getText().toString()); if (v instanceof Button) {
boolean processText = true;
if ( v instanceof ColorButton) {
processText = ((ColorButton) v).isShowText();
}
if ( processText ) {
buttonPressed(((Button)v).getText().toString());
}
} }
} }
private void buttonPressed(@NotNull CalculatorSpecialButton button) {
buttonPressed(button.getActionCode());
}
private void buttonPressed(@NotNull String text) {
getKeyboard().buttonPressed(text);
}
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void functionsButtonClickHandler(@NotNull View v) { public void functionsButtonClickHandler(@NotNull View v) {
CalculatorActivityLauncher.showFunctions(this); buttonPressed(CalculatorSpecialButton.functions);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void operatorsButtonClickHandler(@NotNull View v) { public void operatorsButtonClickHandler(@NotNull View v) {
CalculatorActivityLauncher.showOperators(this); buttonPressed(CalculatorSpecialButton.operators);
}
public static void operatorsButtonClickHandler(@NotNull Activity activity) {
CalculatorActivityLauncher.showOperators(activity);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void varsButtonClickHandler(@NotNull View v) { public void varsButtonClickHandler(@NotNull View v) {
CalculatorActivityLauncher.showVars(this); buttonPressed(CalculatorSpecialButton.vars);
} }
@SuppressWarnings({"UnusedDeclaration"}) @SuppressWarnings({"UnusedDeclaration"})
public void likeButtonClickHandler(@NotNull View v) { public void likeButtonClickHandler(@NotNull View v) {
CalculatorApplication.likeButtonPressed(this); buttonPressed(CalculatorSpecialButton.like);
} }
} }

View File

@ -1,85 +1,138 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import com.actionbarsherlock.app.SherlockFragmentActivity; import android.net.Uri;
import jscl.math.Generic; import com.actionbarsherlock.app.SherlockFragmentActivity;
import jscl.math.function.Constant; import jscl.math.Generic;
import org.achartengine.ChartFactory; import jscl.math.function.Constant;
import org.jetbrains.annotations.NotNull; import org.achartengine.ChartFactory;
import org.solovyev.android.calculator.about.CalculatorAboutActivity; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.help.CalculatorHelpActivity; import org.solovyev.android.calculator.about.CalculatorAboutActivity;
import org.solovyev.android.calculator.history.CalculatorHistoryActivity; import org.solovyev.android.calculator.help.CalculatorHelpActivity;
import org.solovyev.android.calculator.math.edit.*; import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.plot.CalculatorPlotFragment; import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.common.msg.MessageType; import org.solovyev.android.calculator.plot.CalculatorPlotFragment;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils;
/**
* User: serso /**
* Date: 11/2/11 * User: serso
* Time: 2:18 PM * Date: 11/2/11
*/ * Time: 2:18 PM
public class CalculatorActivityLauncher { */
public class CalculatorActivityLauncher {
public static void showHistory(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorHistoryActivity.class)); public static void showHistory(@NotNull final Context context) {
} showHistory(context, false);
}
public static void showHelp(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorHelpActivity.class)); public static void showHistory(@NotNull final Context context, boolean detached) {
} final Intent intent = new Intent(context, CalculatorHistoryActivity.class);
addFlags(intent, detached);
public static void showSettings(@NotNull final Context context) { context.startActivity(intent);
context.startActivity(new Intent(context, CalculatorPreferencesActivity.class)); }
}
public static void showHelp(@NotNull final Context context) {
public static void showAbout(@NotNull final Context context) { context.startActivity(new Intent(context, CalculatorHelpActivity.class));
context.startActivity(new Intent(context, CalculatorAboutActivity.class)); }
}
public static void showSettings(@NotNull final Context context) {
public static void showFunctions(@NotNull final Context context) { showSettings(context, false);
context.startActivity(new Intent(context, CalculatorFunctionsActivity.class)); }
} public static void showSettings(@NotNull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorPreferencesActivity.class);
public static void showOperators(@NotNull final Context context) { addFlags(intent, detached);
context.startActivity(new Intent(context, CalculatorOperatorsActivity.class)); context.startActivity(intent);
} }
public static void showVars(@NotNull final Context context) { private static void addFlags(@NotNull Intent intent, boolean detached) {
context.startActivity(new Intent(context, CalculatorVarsActivity.class)); int flags = Intent.FLAG_ACTIVITY_NEW_TASK;
}
if (detached) {
public static void plotGraph(@NotNull final Context context, @NotNull Generic generic, @NotNull Constant constant){ flags = flags | Intent.FLAG_ACTIVITY_NO_HISTORY;
final Intent intent = new Intent(); }
intent.putExtra(ChartFactory.TITLE, context.getString(R.string.c_graph));
intent.putExtra(CalculatorPlotFragment.INPUT, new CalculatorPlotFragment.Input(generic.toString(), constant.getName())); intent.setFlags(flags);
intent.setClass(context, CalculatorPlotActivity.class);
context.startActivity(intent); }
}
public static void showAbout(@NotNull final Context context) {
public static void createVar(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) { context.startActivity(new Intent(context, CalculatorAboutActivity.class));
final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState(); }
if (viewState.isValid() ) {
final String varValue = viewState.getText(); public static void showFunctions(@NotNull final Context context) {
if (!StringUtils.isEmpty(varValue)) { showHistory(context, false);
if (CalculatorVarsFragment.isValidValue(varValue)) { }
if (context instanceof SherlockFragmentActivity) {
VarEditDialogFragment.showDialog(VarEditDialogFragment.Input.newFromValue(varValue), ((SherlockFragmentActivity) context).getSupportFragmentManager()); public static void showFunctions(@NotNull final Context context, boolean detached) {
} else { final Intent intent = new Intent(context, CalculatorFunctionsActivity.class);
final Intent intent = new Intent(context, CalculatorVarsActivity.class); addFlags(intent, detached);
intent.putExtra(CalculatorVarsFragment.CREATE_VAR_EXTRA_STRING, varValue); context.startActivity(intent);
context.startActivity(intent); }
}
} else { public static void showOperators(@NotNull final Context context) {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error); showOperators(context, false);
} }
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_empty_var_error, MessageType.error); public static void showOperators(@NotNull final Context context, boolean detached) {
} final Intent intent = new Intent(context, CalculatorOperatorsActivity.class);
} else { addFlags(intent, detached);
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error); context.startActivity(intent);
} }
}
} public static void showVars(@NotNull final Context context) {
showVars(context, false);
}
public static void showVars(@NotNull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorVarsActivity.class);
addFlags(intent, detached);
context.startActivity(intent);
}
public static void plotGraph(@NotNull final Context context, @NotNull Generic generic, @NotNull Constant constant){
final Intent intent = new Intent();
intent.putExtra(ChartFactory.TITLE, context.getString(R.string.c_graph));
intent.putExtra(CalculatorPlotFragment.INPUT, new CalculatorPlotFragment.Input(generic.toString(), constant.getName()));
intent.setClass(context, CalculatorPlotActivity.class);
context.startActivity(intent);
}
public static void createVar(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) {
final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState();
if (viewState.isValid() ) {
final String varValue = viewState.getText();
if (!StringUtils.isEmpty(varValue)) {
if (CalculatorVarsFragment.isValidValue(varValue)) {
if (context instanceof SherlockFragmentActivity) {
VarEditDialogFragment.showDialog(VarEditDialogFragment.Input.newFromValue(varValue), ((SherlockFragmentActivity) context).getSupportFragmentManager());
} else {
final Intent intent = new Intent(context, CalculatorVarsActivity.class);
intent.putExtra(CalculatorVarsFragment.CREATE_VAR_EXTRA_STRING, varValue);
context.startActivity(intent);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_empty_var_error, MessageType.error);
}
} else {
CalculatorLocatorImpl.getInstance().getNotifier().showMessage(R.string.c_not_valid_result, MessageType.error);
}
}
public static void openApp(@NotNull Context context) {
final Intent intent = new Intent(context, CalculatorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
public static void likeButtonPressed(@NotNull final Context context) {
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(CalculatorApplication.FACEBOOK_APP_URL));
addFlags(intent, false);
context.startActivity(intent);
}
}

View File

@ -1,9 +1,6 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import net.robotmedia.billing.BillingController; import net.robotmedia.billing.BillingController;
import net.robotmedia.billing.helper.DefaultBillingObserver; import net.robotmedia.billing.helper.DefaultBillingObserver;
@ -15,6 +12,7 @@ import org.jetbrains.annotations.NotNull;
import org.solovyev.android.ads.AdsController; import org.solovyev.android.ads.AdsController;
import org.solovyev.android.calculator.history.AndroidCalculatorHistory; import org.solovyev.android.calculator.history.AndroidCalculatorHistory;
import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
import org.solovyev.android.calculator.widget.CalculatorWidgetHelper;
/** /**
* User: serso * User: serso
@ -39,6 +37,7 @@ public class CalculatorApplication extends android.app.Application {
********************************************************************** **********************************************************************
*/ */
private static final String TAG = "Calculator++ Application";
public static final String FACEBOOK_APP_URL = "http://www.facebook.com/calculatorpp"; public static final String FACEBOOK_APP_URL = "http://www.facebook.com/calculatorpp";
public static final String AD_FREE_PRODUCT_ID = "ad_free"; public static final String AD_FREE_PRODUCT_ID = "ad_free";
@ -49,6 +48,9 @@ public class CalculatorApplication extends android.app.Application {
@NotNull @NotNull
private static CalculatorApplication instance; private static CalculatorApplication instance;
@NotNull
private CalculatorWidgetHelper widgetHelper;
/* /*
********************************************************************** **********************************************************************
* *
@ -91,6 +93,10 @@ public class CalculatorApplication extends android.app.Application {
CalculatorLocatorImpl.getInstance().getCalculator().init(); CalculatorLocatorImpl.getInstance().getCalculator().init();
// in order to not to be garbage collected
widgetHelper = new CalculatorWidgetHelper();
CalculatorLocatorImpl.getInstance().getCalculator().addCalculatorEventListener(widgetHelper);
AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() {
@Override @Override
@ -115,6 +121,9 @@ public class CalculatorApplication extends android.app.Application {
AdsController.getInstance().isAdFree(CalculatorApplication.this); AdsController.getInstance().isAdFree(CalculatorApplication.this);
} }
}).start(); }).start();
CalculatorLocatorImpl.getInstance().getLogger().debug(TAG, "Application started!");
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Application started!");
} }
private void setTheme(@NotNull SharedPreferences preferences) { private void setTheme(@NotNull SharedPreferences preferences) {
@ -154,7 +163,4 @@ public class CalculatorApplication extends android.app.Application {
return instance; return instance;
} }
public static void likeButtonPressed(@NotNull final Context context) {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(FACEBOOK_APP_URL)));
}
} }

View File

@ -1,37 +1,37 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
*/ */
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.drag.DragDirection; import org.solovyev.android.view.drag.DirectionDragButton;
import org.solovyev.android.view.drag.SimpleOnDragListener; import org.solovyev.android.view.drag.DragButton;
import org.solovyev.android.view.drag.DirectionDragButton; import org.solovyev.android.view.drag.DragDirection;
import org.solovyev.android.view.drag.DragButton; import org.solovyev.android.view.drag.SimpleOnDragListener;
import org.solovyev.common.math.Point2d; import org.solovyev.common.math.Point2d;
/** /**
* User: serso * User: serso
* Date: 9/16/11 * Date: 9/16/11
* Time: 11:48 PM * Time: 11:48 PM
*/ */
public class DigitButtonDragProcessor implements SimpleOnDragListener.DragProcessor { public class DigitButtonDragProcessor implements SimpleOnDragListener.DragProcessor {
@NotNull @NotNull
private CalculatorKeyboard calculatorKeyboard; private CalculatorKeyboard calculatorKeyboard;
public DigitButtonDragProcessor(@NotNull CalculatorKeyboard calculatorKeyboard) { public DigitButtonDragProcessor(@NotNull CalculatorKeyboard calculatorKeyboard) {
this.calculatorKeyboard = calculatorKeyboard; this.calculatorKeyboard = calculatorKeyboard;
} }
@Override @Override
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) { public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
assert dragButton instanceof DirectionDragButton; assert dragButton instanceof DirectionDragButton;
calculatorKeyboard.digitButtonPressed(((DirectionDragButton) dragButton).getText(dragDirection)); calculatorKeyboard.buttonPressed(((DirectionDragButton) dragButton).getText(dragDirection));
return true; return true;
} }
} }

View File

@ -71,7 +71,7 @@ public class NumeralBaseConverterDialog {
toUnitsValue = ((CalculatorNumeralBase) toUnits.getUnitType()).getNumeralBase().getJsclPrefix() + toUnitsValue; toUnitsValue = ((CalculatorNumeralBase) toUnits.getUnitType()).getNumeralBase().getJsclPrefix() + toUnitsValue;
} }
CalculatorLocatorImpl.getInstance().getKeyboard().digitButtonPressed(toUnitsValue); CalculatorLocatorImpl.getInstance().getKeyboard().buttonPressed(toUnitsValue);
final AlertDialog alertDialog = alertDialogHolder.getObject(); final AlertDialog alertDialog = alertDialogHolder.getObject();
if (alertDialog != null) { if (alertDialog != null) {
alertDialog.dismiss(); alertDialog.dismiss();

View File

@ -0,0 +1,11 @@
package org.solovyev.android.calculator.widget;
import android.app.Activity;
/**
* User: Solovyev_S
* Date: 19.10.12
* Time: 16:20
*/
public class CalculatorWidgetConfigurationActivity extends Activity {
}

View File

@ -0,0 +1,65 @@
package org.solovyev.android.calculator.widget;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.*;
/**
* User: serso
* Date: 10/19/12
* Time: 11:11 PM
*/
public class CalculatorWidgetHelper extends BroadcastReceiver implements CalculatorEventListener {
private static final String TAG = "Calculator++ Widget Helper";
@NotNull
private final CalculatorEventHolder lastEvent = new CalculatorEventHolder(CalculatorUtils.createFirstEventDataId());
public CalculatorWidgetHelper() {
CalculatorLocatorImpl.getInstance().getCalculator().addCalculatorEventListener(this);
}
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
final CalculatorEventHolder.Result result = lastEvent.apply(calculatorEventData);
if (result.isNewAfter()) {
switch (calculatorEventType) {
case editor_state_changed_light:
case editor_state_changed:
final CalculatorEditorChangeEventData editorChangeData = (CalculatorEditorChangeEventData) data;
final CalculatorEditorViewState newEditorState = editorChangeData.getNewValue();
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed: " + newEditorState.getText());
CalculatorWidgetProvider.onEditorStateChanged(CalculatorApplication.getInstance(), newEditorState);
break;
case display_state_changed:
final CalculatorDisplayChangeEventData displayChangeData = (CalculatorDisplayChangeEventData) data;
final CalculatorDisplayViewState newDisplayState = displayChangeData.getNewValue();
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed: " + newDisplayState.getText());
CalculatorWidgetProvider.onDisplayStateChanged(CalculatorApplication.getInstance(), newDisplayState);
break;
}
}
}
@Override
public void onReceive(Context context, Intent intent) {
if (CalculatorWidgetProvider.BUTTON_PRESSED_ACTION.equals(intent.getAction())) {
final int buttonId = intent.getIntExtra(CalculatorWidgetProvider.BUTTON_ID_EXTRA, 0);
//Toast.makeText(context, "Button id: " + buttonId, Toast.LENGTH_SHORT).show();
final WidgetButton button = WidgetButton.getById(buttonId);
if ( button != null ) {
button.onClick(context);
}
}
}
}

View File

@ -0,0 +1,199 @@
package org.solovyev.android.calculator.widget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.text.Html;
import android.widget.RemoteViews;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorDisplayViewState;
import org.solovyev.android.calculator.CalculatorEditorViewState;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.R;
import java.io.Serializable;
/**
* User: Solovyev_S
* Date: 19.10.12
* Time: 16:18
*/
public class CalculatorWidgetProvider extends AppWidgetProvider {
/*
**********************************************************************
*
* CONSTANTS
*
**********************************************************************
*/
public static final String BUTTON_ID_EXTRA = "buttonId";
public static final String BUTTON_PRESSED_ACTION = "org.solovyev.calculator.widget.BUTTON_PRESSED";
private static final String EDITOR_STATE_CHANGED_ACTION = "org.solovyev.calculator.widget.EDITOR_STATE_CHANGED";
private static final String EDITOR_STATE_EXTRA = "editorState";
private static final String DISPLAY_STATE_CHANGED_ACTION = "org.solovyev.calculator.widget.DISPLAY_STATE_CHANGED";
private static final String DISPLAY_STATE_EXTRA = "displayState";
private static final String TAG = "Calculator++ Widget";
/*
**********************************************************************
*
* FIELDS
*
**********************************************************************
*/
@Nullable
private String cursorColor;
/*
**********************************************************************
*
* METHODS
*
**********************************************************************
*/
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
getCursorColor(context);
}
@NotNull
private String getCursorColor(@NotNull Context context) {
if ( cursorColor == null ) {
cursorColor = Integer.toHexString(context.getResources().getColor(R.color.widget_cursor_color)).substring(2);
}
return cursorColor;
}
@Override
public void onUpdate(@NotNull Context context,
@NotNull AppWidgetManager appWidgetManager,
@NotNull int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int appWidgetId : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
for (WidgetButton button : WidgetButton.values()) {
final Intent onButtonClickIntent = new Intent(context, CalculatorWidgetProvider.class);
onButtonClickIntent.setAction(BUTTON_PRESSED_ACTION);
onButtonClickIntent.putExtra(BUTTON_ID_EXTRA, button.getButtonId());
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, button.getButtonId(), onButtonClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (pendingIntent != null) {
views.setOnClickPendingIntent(button.getButtonId(), pendingIntent);
}
}
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (CalculatorWidgetProvider.BUTTON_PRESSED_ACTION.equals(intent.getAction())) {
final int buttonId = intent.getIntExtra(CalculatorWidgetProvider.BUTTON_ID_EXTRA, 0);
final WidgetButton button = WidgetButton.getById(buttonId);
if (button != null) {
button.onClick(context);
}
} else if (EDITOR_STATE_CHANGED_ACTION.equals(intent.getAction())) {
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed broadcast received!");
final Serializable object = intent.getSerializableExtra(EDITOR_STATE_EXTRA);
if (object instanceof CalculatorEditorViewState) {
updateEditorState(context, (CalculatorEditorViewState) object);
}
} else if (DISPLAY_STATE_CHANGED_ACTION.equals(intent.getAction())) {
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed broadcast received!");
final Serializable object = intent.getSerializableExtra(DISPLAY_STATE_EXTRA);
if (object instanceof CalculatorDisplayViewState) {
updateDisplayState(context, (CalculatorDisplayViewState) object);
}
}
}
private void updateDisplayState(@NotNull Context context, @NotNull CalculatorDisplayViewState displayState) {
if (displayState.isValid()) {
setText(context, R.id.calculatorDisplay, displayState.getText());
setTextColor(context, R.id.calculatorDisplay, context.getResources().getColor(R.color.default_text_color));
} else {
setTextColor(context, R.id.calculatorDisplay, context.getResources().getColor(R.color.display_error_text_color));
}
}
private void setText(@NotNull Context context, int textViewId, @Nullable CharSequence text) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, CalculatorWidgetProvider.class));
for (int appWidgetId : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setTextViewText(textViewId, text);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
private void setTextColor(@NotNull Context context, int textViewId, int textColor) {
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, CalculatorWidgetProvider.class));
for (int appWidgetId : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setTextColor(textViewId, textColor);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
private void updateEditorState(@NotNull Context context, @NotNull CalculatorEditorViewState editorState) {
String text = editorState.getText();
CharSequence newText = text;
int selection = editorState.getSelection();
if (selection >= 0 && selection <= text.length() ) {
// inject cursor
newText = Html.fromHtml(text.substring(0, selection) + "<font color=\"#" + getCursorColor(context) + "\">|</font>" + text.substring(selection));
}
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "New editor state: " + text);
setText(context, R.id.calculatorEditor, newText);
}
/*
**********************************************************************
*
* STATIC
*
**********************************************************************
*/
public static void onEditorStateChanged(@NotNull Context context, @NotNull CalculatorEditorViewState editorViewState) {
final Intent intent = new Intent(EDITOR_STATE_CHANGED_ACTION);
intent.setClass(context, CalculatorWidgetProvider.class);
intent.putExtra(EDITOR_STATE_EXTRA, editorViewState);
context.sendBroadcast(intent);
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Editor state changed broadcast sent");
}
public static void onDisplayStateChanged(@NotNull Context context, @NotNull CalculatorDisplayViewState displayViewState) {
final Intent intent = new Intent(DISPLAY_STATE_CHANGED_ACTION);
intent.setClass(context, CalculatorWidgetProvider.class);
intent.putExtra(DISPLAY_STATE_EXTRA, displayViewState);
context.sendBroadcast(intent);
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Display state changed broadcast sent");
}
}

View File

@ -0,0 +1,94 @@
package org.solovyev.android.calculator.widget;
import android.content.Context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.CalculatorSpecialButton;
import org.solovyev.android.calculator.R;
/**
* User: serso
* Date: 10/20/12
* Time: 12:05 AM
*/
enum WidgetButton {
/*digits*/
one(R.id.oneDigitButton, "1"),
two(R.id.twoDigitButton, "2"),
three(R.id.threeDigitButton, "3"),
four(R.id.fourDigitButton, "4"),
five(R.id.fiveDigitButton, "5"),
six(R.id.sixDigitButton, "6"),
seven(R.id.sevenDigitButton, "7"),
eight(R.id.eightDigitButton, "8"),
nine(R.id.nineDigitButton, "9"),
zero(R.id.zeroDigitButton, "0"),
period(R.id.periodButton, "."),
brackets(R.id.roundBracketsButton, "()"),
settings(R.id.settingsButton, CalculatorSpecialButton.settings_detached),
like(R.id.likeButton, CalculatorSpecialButton.like),
/*last row*/
left(R.id.leftButton, CalculatorSpecialButton.cursor_left),
right(R.id.rightButton, CalculatorSpecialButton.cursor_right),
vars(R.id.varsButton, CalculatorSpecialButton.vars_detached),
functions(R.id.functionsButton, CalculatorSpecialButton.functions_detached),
app(R.id.appButton, CalculatorSpecialButton.open_app),
history(R.id.historyButton, CalculatorSpecialButton.history_detached),
/*operations*/
multiplication(R.id.multiplicationButton, "*"),
division(R.id.divisionButton, "/"),
plus(R.id.plusButton, "+"),
subtraction(R.id.subtractionButton, "-"),
percent(R.id.percentButton, "%"),
power(R.id.powerButton, "^"),
/*last column*/
clear(R.id.clearButton, CalculatorSpecialButton.clear),
erase(R.id.eraseButton, CalculatorSpecialButton.erase),
copy(R.id.copyButton, CalculatorSpecialButton.copy),
paste(R.id.pasteButton, CalculatorSpecialButton.paste),
/*equals*/
equals(R.id.equalsButton, CalculatorSpecialButton.equals);
private final int buttonId;
@NotNull
private final String text;
WidgetButton(int buttonId, @NotNull CalculatorSpecialButton button) {
this(buttonId, button.getActionCode());
}
WidgetButton(int buttonId, @NotNull String text) {
this.buttonId = buttonId;
this.text = text;
}
public void onClick(@NotNull Context context) {
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage("Calculator++ Widget", "Button pressed: " + text);
CalculatorLocatorImpl.getInstance().getKeyboard().buttonPressed(text);
}
@Nullable
public static WidgetButton getById(int buttonId) {
for (WidgetButton widgetButton : values()) {
if (widgetButton.buttonId == buttonId) {
return widgetButton;
}
}
return null;
}
public int getButtonId() {
return buttonId;
}
}