Calculator++ widget

This commit is contained in:
Sergey Solovyev
2012-10-20 16:22:25 +04:00
parent 42acacee32
commit bf0aa44f4f
85 changed files with 2708 additions and 1960 deletions

View File

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

View File

@@ -1,191 +1,218 @@
package org.solovyev.android.calculator;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.history.HistoryAction;
import java.util.List;
/**
* User: serso
* Date: 9/22/12
* Time: 5:42 PM
*/
public class AndroidCalculator implements Calculator, CalculatorEventListener {
@NotNull
private final Calculator calculator = new CalculatorImpl();
public AndroidCalculator() {
this.calculator.addCalculatorEventListener(this);
}
public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setPositiveButton(R.string.c_cancel, null)
.setView(errorMessageView);
builder.create().show();
}
public void init(@NotNull final Activity activity) {
setEditor(activity);
setDisplay(activity);
}
public void setDisplay(@NotNull Activity activity) {
final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
setDisplay(activity, displayView);
}
public void setDisplay(@NotNull Context context, @NotNull AndroidCalculatorDisplayView displayView) {
displayView.init(context);
CalculatorLocatorImpl.getInstance().getDisplay().setView(displayView);
}
public void setEditor(@NotNull Activity activity) {
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
setEditor(activity, editorView);
}
public void setEditor(@NotNull Context context, @NotNull AndroidCalculatorEditorView editorView) {
editorView.init(context);
CalculatorLocatorImpl.getInstance().getEditor().setView(editorView);
}
/*
**********************************************************************
*
* DELEGATED TO CALCULATOR
*
**********************************************************************
*/
@Override
@NotNull
public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression) {
return calculator.evaluate(operation, expression);
}
@Override
@NotNull
public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression, @NotNull Long sequenceId) {
return calculator.evaluate(operation, expression, sequenceId);
}
@Override
public boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to) {
return calculator.isConversionPossible(generic, from, to);
}
@Override
@NotNull
public CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to) {
return calculator.convert(generic, to);
}
@Override
@NotNull
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
return calculator.fireCalculatorEvent(calculatorEventType, data);
}
@NotNull
@Override
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Object source) {
return calculator.fireCalculatorEvent(calculatorEventType, data, source);
}
@Override
@NotNull
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId) {
return calculator.fireCalculatorEvent(calculatorEventType, data, sequenceId);
}
@Override
public void init() {
this.calculator.init();
}
@Override
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
calculator.addCalculatorEventListener(calculatorEventListener);
}
@Override
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
calculator.removeCalculatorEventListener(calculatorEventListener);
}
@Override
public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
calculator.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
}
@Override
public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) {
calculator.fireCalculatorEvents(calculatorEvents);
}
@Override
public void doHistoryAction(@NotNull HistoryAction historyAction) {
calculator.doHistoryAction(historyAction);
}
@Override
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
calculator.setCurrentHistoryState(editorHistoryState);
}
@Override
@NotNull
public CalculatorHistoryState getCurrentHistoryState() {
return calculator.getCurrentHistoryState();
}
@Override
public void evaluate() {
calculator.evaluate();
}
@Override
public void evaluate(@NotNull Long sequenceId) {
calculator.evaluate(sequenceId);
}
@Override
public void 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_functions:
CalculatorActivityLauncher.showFunctions(CalculatorApplication.getInstance());
break;
case show_vars:
CalculatorActivityLauncher.showVars(CalculatorApplication.getInstance());
break;
}
}
}
package org.solovyev.android.calculator;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import jscl.NumeralBase;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.CalculatorHistoryState;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.history.HistoryAction;
import java.util.List;
/**
* User: serso
* Date: 9/22/12
* Time: 5:42 PM
*/
public class AndroidCalculator implements Calculator, CalculatorEventListener {
@NotNull
private final Calculator calculator = new CalculatorImpl();
public AndroidCalculator() {
this.calculator.addCalculatorEventListener(this);
}
public static void showEvaluationError(@NotNull Context context, @NotNull final String errorMessage) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
final View errorMessageView = layoutInflater.inflate(R.layout.display_error_message, null);
((TextView) errorMessageView.findViewById(R.id.error_message_text_view)).setText(errorMessage);
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setPositiveButton(R.string.c_cancel, null)
.setView(errorMessageView);
builder.create().show();
}
public void init(@NotNull final Activity activity) {
setEditor(activity);
setDisplay(activity);
}
public void setDisplay(@NotNull Activity activity) {
final AndroidCalculatorDisplayView displayView = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
setDisplay(activity, displayView);
}
public void setDisplay(@NotNull Context context, @NotNull AndroidCalculatorDisplayView displayView) {
displayView.init(context);
CalculatorLocatorImpl.getInstance().getDisplay().setView(displayView);
}
public void setEditor(@NotNull Activity activity) {
final AndroidCalculatorEditorView editorView = (AndroidCalculatorEditorView) activity.findViewById(R.id.calculatorEditor);
setEditor(activity, editorView);
}
public void setEditor(@NotNull Context context, @NotNull AndroidCalculatorEditorView editorView) {
editorView.init(context);
CalculatorLocatorImpl.getInstance().getEditor().setView(editorView);
}
/*
**********************************************************************
*
* DELEGATED TO CALCULATOR
*
**********************************************************************
*/
@Override
@NotNull
public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression) {
return calculator.evaluate(operation, expression);
}
@Override
@NotNull
public CalculatorEventData evaluate(@NotNull JsclOperation operation, @NotNull String expression, @NotNull Long sequenceId) {
return calculator.evaluate(operation, expression, sequenceId);
}
@Override
public boolean isConversionPossible(@NotNull Generic generic, @NotNull NumeralBase from, @NotNull NumeralBase to) {
return calculator.isConversionPossible(generic, from, to);
}
@Override
@NotNull
public CalculatorEventData convert(@NotNull Generic generic, @NotNull NumeralBase to) {
return calculator.convert(generic, to);
}
@Override
@NotNull
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
return calculator.fireCalculatorEvent(calculatorEventType, data);
}
@NotNull
@Override
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Object source) {
return calculator.fireCalculatorEvent(calculatorEventType, data, source);
}
@Override
@NotNull
public CalculatorEventData fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId) {
return calculator.fireCalculatorEvent(calculatorEventType, data, sequenceId);
}
@Override
public void init() {
this.calculator.init();
}
@Override
public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
calculator.addCalculatorEventListener(calculatorEventListener);
}
@Override
public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) {
calculator.removeCalculatorEventListener(calculatorEventListener);
}
@Override
public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
calculator.fireCalculatorEvent(calculatorEventData, calculatorEventType, data);
}
@Override
public void fireCalculatorEvents(@NotNull List<CalculatorEvent> calculatorEvents) {
calculator.fireCalculatorEvents(calculatorEvents);
}
@Override
public void doHistoryAction(@NotNull HistoryAction historyAction) {
calculator.doHistoryAction(historyAction);
}
@Override
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
calculator.setCurrentHistoryState(editorHistoryState);
}
@Override
@NotNull
public CalculatorHistoryState getCurrentHistoryState() {
return calculator.getCurrentHistoryState();
}
@Override
public void evaluate() {
calculator.evaluate();
}
@Override
public void evaluate(@NotNull Long sequenceId) {
calculator.evaluate(sequenceId);
}
@Override
public void 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;
// NOTE: static because super constructor calls some overridden methods (like onSelectionChanged and current lock is not yet created)
@NotNull
private static final Object viewLock = new Object();
@Nullable
private final Object viewLock = new Object();
@NotNull
private final Handler uiHandler = new Handler();
@@ -154,45 +153,51 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe
@Override
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() {
@Override
public void run() {
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
synchronized (viewLock) {
try {
editorView.viewStateChange = true;
editorView.viewState = viewState;
editorView.setText(text, BufferType.EDITABLE);
editorView.setSelection(viewState.getSelection());
} finally {
editorView.viewStateChange = false;
uiHandler.post(new Runnable() {
@Override
public void run() {
final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this;
synchronized (viewLock) {
try {
editorView.viewStateChange = true;
editorView.viewState = viewState;
editorView.setText(text, BufferType.EDITABLE);
editorView.setSelection(viewState.getSelection());
} finally {
editorView.viewStateChange = false;
}
}
}
}
});
});
}
}
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
synchronized (viewLock) {
if (!viewStateChange) {
// external text change => need to notify editor
super.onSelectionChanged(selStart, selEnd);
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
if (viewLock != null) {
synchronized (viewLock) {
if (!viewStateChange) {
// external text change => need to notify editor
super.onSelectionChanged(selStart, selEnd);
CalculatorLocatorImpl.getInstance().getEditor().setSelection(selStart);
}
}
}
}
public void handleTextChange(Editable s) {
synchronized (viewLock) {
if (!viewStateChange) {
// external text change => need to notify editor
CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s));
if (viewLock != null) {
synchronized (viewLock) {
if (!viewStateChange) {
// 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;
import android.app.Application;
import android.os.Handler;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils2;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType;
@@ -20,13 +22,18 @@ public class AndroidCalculatorNotifier implements CalculatorNotifier {
@NotNull
private final Application application;
@NotNull
private final Handler uiHandler = new Handler();
public AndroidCalculatorNotifier(@NotNull Application application) {
assert AndroidUtils2.isUiThread();
this.application = application;
}
@Override
public void showMessage(@NotNull Message message) {
Toast.makeText(application, message.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
showMessageInUiThread(message.getLocalizedMessage());
}
@Override
@@ -38,4 +45,25 @@ public class AndroidCalculatorNotifier implements CalculatorNotifier {
public void showMessage(@NotNull Integer messageCode, @NotNull MessageType messageType, @Nullable Object... 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

@@ -1,318 +1,322 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
*/
package org.solovyev.android.calculator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils;
import org.solovyev.android.calculator.about.CalculatorFragmentType;
import org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment;
import org.solovyev.android.fragments.FragmentUtils;
import org.solovyev.android.prefs.Preference;
import org.solovyev.android.view.ColorButton;
import org.solovyev.common.equals.EqualsTool;
import org.solovyev.common.history.HistoryAction;
import org.solovyev.common.text.StringUtils;
public class CalculatorActivity extends SherlockFragmentActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@NotNull
public static final String TAG = CalculatorActivity.class.getSimpleName();
private boolean useBackAsPrev;
@NotNull
private CalculatorActivityHelper activityHelper;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final CalculatorPreferences.Gui.Layout layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences);
activityHelper = CalculatorApplication.getInstance().createActivityHelper(layout.getLayoutId(), TAG);
activityHelper.logDebug("onCreate");
activityHelper.onCreate(this, savedInstanceState);
super.onCreate(savedInstanceState);
activityHelper.logDebug("super.onCreate");
if (findViewById(R.id.main_second_pane) != null) {
activityHelper.addTab(this, CalculatorFragmentType.history, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.saved_history, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.variables, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.functions, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.operators, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.plotter, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.faq, null, R.id.main_second_pane);
} else {
getSupportActionBar().hide();
}
FragmentUtils.createFragment(this, CalculatorEditorFragment.class, R.id.editorContainer, "editor");
FragmentUtils.createFragment(this, CalculatorDisplayFragment.class, R.id.displayContainer, "display");
FragmentUtils.createFragment(this, CalculatorKeyboardFragment.class, R.id.keyboardContainer, "keyboard");
this.useBackAsPrev = CalculatorPreferences.Gui.usePrevAsBack.getPreference(preferences);
firstTimeInit(preferences, this);
toggleOrientationChange(preferences);
preferences.registerOnSharedPreferenceChangeListener(this);
}
@NotNull
private AndroidCalculator getCalculator() {
return ((AndroidCalculator) CalculatorLocatorImpl.getInstance().getCalculator());
}
private static void firstTimeInit(@NotNull SharedPreferences preferences, @NotNull Context context) {
final Integer appOpenedCounter = CalculatorPreferences.appOpenedCounter.getPreference(preferences);
if (appOpenedCounter != null) {
CalculatorPreferences.appOpenedCounter.putPreference(preferences, appOpenedCounter + 1);
}
final Integer savedVersion = CalculatorPreferences.appVersion.getPreference(preferences);
final int appVersion = AndroidUtils.getAppVersionCode(context, CalculatorActivity.class.getPackage().getName());
CalculatorPreferences.appVersion.putPreference(preferences, appVersion);
boolean dialogShown = false;
if (EqualsTool.areEqual(savedVersion, CalculatorPreferences.appVersion.getDefaultValue())) {
// new start
final AlertDialog.Builder builder = new AlertDialog.Builder(context).setMessage(R.string.c_first_start_text);
builder.setPositiveButton(android.R.string.ok, null);
builder.setTitle(R.string.c_first_start_text_title);
builder.create().show();
dialogShown = true;
} else {
if (savedVersion < appVersion) {
final boolean showReleaseNotes = CalculatorPreferences.Gui.showReleaseNotes.getPreference(preferences);
if (showReleaseNotes) {
final String releaseNotes = CalculatorReleaseNotesFragment.getReleaseNotes(context, savedVersion + 1);
if (!StringUtils.isEmpty(releaseNotes)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context).setMessage(Html.fromHtml(releaseNotes));
builder.setPositiveButton(android.R.string.ok, null);
builder.setTitle(R.string.c_release_notes);
builder.create().show();
dialogShown = true;
}
}
}
}
//Log.d(this.getClass().getName(), "Application was opened " + appOpenedCounter + " time!");
if (!dialogShown) {
if (appOpenedCounter != null && appOpenedCounter > 10) {
dialogShown = showSpecialWindow(preferences, CalculatorPreferences.Gui.feedbackWindowShown, R.layout.feedback, R.id.feedbackText, context);
}
}
}
private static boolean showSpecialWindow(@NotNull SharedPreferences preferences, @NotNull Preference<Boolean> specialWindowShownPref, int layoutId, int textViewId, @NotNull Context context) {
boolean result = false;
final Boolean specialWindowShown = specialWindowShownPref.getPreference(preferences);
if ( specialWindowShown != null && !specialWindowShown ) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
final View view = layoutInflater.inflate(layoutId, null);
final TextView feedbackTextView = (TextView) view.findViewById(textViewId);
feedbackTextView.setMovementMethod(LinkMovementMethod.getInstance());
final AlertDialog.Builder builder = new AlertDialog.Builder(context).setView(view);
builder.setPositiveButton(android.R.string.ok, null);
builder.create().show();
result = true;
specialWindowShownPref.putPreference(preferences, true);
}
return result;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (useBackAsPrev) {
getCalculator().doHistoryAction(HistoryAction.undo);
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@SuppressWarnings({"UnusedDeclaration"})
public void equalsButtonClickHandler(@NotNull View v) {
getCalculator().evaluate();
}
@Override
protected void onPause() {
this.activityHelper.onPause(this);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final CalculatorPreferences.Gui.Layout newLayout = CalculatorPreferences.Gui.layout.getPreference(preferences);
if ( newLayout != activityHelper.getLayout() ) {
AndroidUtils.restartActivity(this);
}
this.activityHelper.onResume(this);
}
@Override
protected void onDestroy() {
activityHelper.onDestroy(this);
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String key) {
if ( CalculatorPreferences.Gui.usePrevAsBack.getKey().equals(key) ) {
useBackAsPrev = CalculatorPreferences.Gui.usePrevAsBack.getPreference(preferences);
}
if ( CalculatorPreferences.Gui.autoOrientation.getKey().equals(key) ) {
toggleOrientationChange(preferences);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
activityHelper.onSaveInstanceState(this, outState);
}
private void toggleOrientationChange(@Nullable SharedPreferences preferences) {
preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(this) : preferences;
if (CalculatorPreferences.Gui.autoOrientation.getPreference(preferences)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
/*
**********************************************************************
*
* BUTTON HANDLERS
*
**********************************************************************
*/
@SuppressWarnings({"UnusedDeclaration"})
public void elementaryButtonClickHandler(@NotNull View v) {
throw new UnsupportedOperationException("Not implemented yet!");
}
@SuppressWarnings({"UnusedDeclaration"})
public void historyButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.SHOW_HISTORY);
}
@SuppressWarnings({"UnusedDeclaration"})
public void eraseButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.ERASE);
}
@SuppressWarnings({"UnusedDeclaration"})
public void simplifyButtonClickHandler(@NotNull View v) {
throw new UnsupportedOperationException("Not implemented yet!");
}
@SuppressWarnings({"UnusedDeclaration"})
public void pasteButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.PASTE);
}
@SuppressWarnings({"UnusedDeclaration"})
public void copyButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.COPY);
}
@NotNull
private static CalculatorKeyboard getKeyboard() {
return CalculatorLocatorImpl.getInstance().getKeyboard();
}
@SuppressWarnings({"UnusedDeclaration"})
public void clearButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.CLEAR);
}
@SuppressWarnings({"UnusedDeclaration"})
public void digitButtonClickHandler(@NotNull View v) {
Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed());
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 String text) {
getKeyboard().buttonPressed(text);
}
@SuppressWarnings({"UnusedDeclaration"})
public void functionsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.SHOW_FUNCTIONS);
}
@SuppressWarnings({"UnusedDeclaration"})
public void operatorsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.SHOW_OPERATORS);
}
@SuppressWarnings({"UnusedDeclaration"})
public void varsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorButtonActions.SHOW_VARS);
}
@SuppressWarnings({"UnusedDeclaration"})
public void likeButtonClickHandler(@NotNull View v) {
CalculatorApplication.likeButtonPressed(this);
}
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
*/
package org.solovyev.android.calculator;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils;
import org.solovyev.android.calculator.about.CalculatorFragmentType;
import org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment;
import org.solovyev.android.fragments.FragmentUtils;
import org.solovyev.android.prefs.Preference;
import org.solovyev.android.view.ColorButton;
import org.solovyev.common.equals.EqualsTool;
import org.solovyev.common.history.HistoryAction;
import org.solovyev.common.text.StringUtils;
public class CalculatorActivity extends SherlockFragmentActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@NotNull
public static final String TAG = CalculatorActivity.class.getSimpleName();
private boolean useBackAsPrev;
@NotNull
private CalculatorActivityHelper activityHelper;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final CalculatorPreferences.Gui.Layout layout = CalculatorPreferences.Gui.layout.getPreferenceNoError(preferences);
activityHelper = CalculatorApplication.getInstance().createActivityHelper(layout.getLayoutId(), TAG);
activityHelper.logDebug("onCreate");
activityHelper.onCreate(this, savedInstanceState);
super.onCreate(savedInstanceState);
activityHelper.logDebug("super.onCreate");
if (findViewById(R.id.main_second_pane) != null) {
activityHelper.addTab(this, CalculatorFragmentType.history, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.saved_history, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.variables, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.functions, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.operators, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.plotter, null, R.id.main_second_pane);
activityHelper.addTab(this, CalculatorFragmentType.faq, null, R.id.main_second_pane);
} else {
getSupportActionBar().hide();
}
FragmentUtils.createFragment(this, CalculatorEditorFragment.class, R.id.editorContainer, "editor");
FragmentUtils.createFragment(this, CalculatorDisplayFragment.class, R.id.displayContainer, "display");
FragmentUtils.createFragment(this, CalculatorKeyboardFragment.class, R.id.keyboardContainer, "keyboard");
this.useBackAsPrev = CalculatorPreferences.Gui.usePrevAsBack.getPreference(preferences);
firstTimeInit(preferences, this);
toggleOrientationChange(preferences);
preferences.registerOnSharedPreferenceChangeListener(this);
}
@NotNull
private AndroidCalculator getCalculator() {
return ((AndroidCalculator) CalculatorLocatorImpl.getInstance().getCalculator());
}
private static void firstTimeInit(@NotNull SharedPreferences preferences, @NotNull Context context) {
final Integer appOpenedCounter = CalculatorPreferences.appOpenedCounter.getPreference(preferences);
if (appOpenedCounter != null) {
CalculatorPreferences.appOpenedCounter.putPreference(preferences, appOpenedCounter + 1);
}
final Integer savedVersion = CalculatorPreferences.appVersion.getPreference(preferences);
final int appVersion = AndroidUtils.getAppVersionCode(context, CalculatorActivity.class.getPackage().getName());
CalculatorPreferences.appVersion.putPreference(preferences, appVersion);
boolean dialogShown = false;
if (EqualsTool.areEqual(savedVersion, CalculatorPreferences.appVersion.getDefaultValue())) {
// new start
final AlertDialog.Builder builder = new AlertDialog.Builder(context).setMessage(R.string.c_first_start_text);
builder.setPositiveButton(android.R.string.ok, null);
builder.setTitle(R.string.c_first_start_text_title);
builder.create().show();
dialogShown = true;
} else {
if (savedVersion < appVersion) {
final boolean showReleaseNotes = CalculatorPreferences.Gui.showReleaseNotes.getPreference(preferences);
if (showReleaseNotes) {
final String releaseNotes = CalculatorReleaseNotesFragment.getReleaseNotes(context, savedVersion + 1);
if (!StringUtils.isEmpty(releaseNotes)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context).setMessage(Html.fromHtml(releaseNotes));
builder.setPositiveButton(android.R.string.ok, null);
builder.setTitle(R.string.c_release_notes);
builder.create().show();
dialogShown = true;
}
}
}
}
//Log.d(this.getClass().getName(), "Application was opened " + appOpenedCounter + " time!");
if (!dialogShown) {
if (appOpenedCounter != null && appOpenedCounter > 10) {
dialogShown = showSpecialWindow(preferences, CalculatorPreferences.Gui.feedbackWindowShown, R.layout.feedback, R.id.feedbackText, context);
}
}
}
private static boolean showSpecialWindow(@NotNull SharedPreferences preferences, @NotNull Preference<Boolean> specialWindowShownPref, int layoutId, int textViewId, @NotNull Context context) {
boolean result = false;
final Boolean specialWindowShown = specialWindowShownPref.getPreference(preferences);
if ( specialWindowShown != null && !specialWindowShown ) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
final View view = layoutInflater.inflate(layoutId, null);
final TextView feedbackTextView = (TextView) view.findViewById(textViewId);
feedbackTextView.setMovementMethod(LinkMovementMethod.getInstance());
final AlertDialog.Builder builder = new AlertDialog.Builder(context).setView(view);
builder.setPositiveButton(android.R.string.ok, null);
builder.create().show();
result = true;
specialWindowShownPref.putPreference(preferences, true);
}
return result;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (useBackAsPrev) {
getCalculator().doHistoryAction(HistoryAction.undo);
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@SuppressWarnings({"UnusedDeclaration"})
public void equalsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.equals);
}
@Override
protected void onPause() {
this.activityHelper.onPause(this);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final CalculatorPreferences.Gui.Layout newLayout = CalculatorPreferences.Gui.layout.getPreference(preferences);
if ( newLayout != activityHelper.getLayout() ) {
AndroidUtils.restartActivity(this);
}
this.activityHelper.onResume(this);
}
@Override
protected void onDestroy() {
activityHelper.onDestroy(this);
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, @Nullable String key) {
if ( CalculatorPreferences.Gui.usePrevAsBack.getKey().equals(key) ) {
useBackAsPrev = CalculatorPreferences.Gui.usePrevAsBack.getPreference(preferences);
}
if ( CalculatorPreferences.Gui.autoOrientation.getKey().equals(key) ) {
toggleOrientationChange(preferences);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
activityHelper.onSaveInstanceState(this, outState);
}
private void toggleOrientationChange(@Nullable SharedPreferences preferences) {
preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(this) : preferences;
if (CalculatorPreferences.Gui.autoOrientation.getPreference(preferences)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
/*
**********************************************************************
*
* BUTTON HANDLERS
*
**********************************************************************
*/
@SuppressWarnings({"UnusedDeclaration"})
public void elementaryButtonClickHandler(@NotNull View v) {
throw new UnsupportedOperationException("Not implemented yet!");
}
@SuppressWarnings({"UnusedDeclaration"})
public void historyButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.history);
}
@SuppressWarnings({"UnusedDeclaration"})
public void eraseButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.erase);
}
@SuppressWarnings({"UnusedDeclaration"})
public void simplifyButtonClickHandler(@NotNull View v) {
throw new UnsupportedOperationException("Not implemented yet!");
}
@SuppressWarnings({"UnusedDeclaration"})
public void pasteButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.paste);
}
@SuppressWarnings({"UnusedDeclaration"})
public void copyButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.copy);
}
@NotNull
private static CalculatorKeyboard getKeyboard() {
return CalculatorLocatorImpl.getInstance().getKeyboard();
}
@SuppressWarnings({"UnusedDeclaration"})
public void clearButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.clear);
}
@SuppressWarnings({"UnusedDeclaration"})
public void digitButtonClickHandler(@NotNull View v) {
Log.d(String.valueOf(v.getId()), "digitButtonClickHandler() for: " + v.getId() + ". Pressed: " + v.isPressed());
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"})
public void functionsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.functions);
}
@SuppressWarnings({"UnusedDeclaration"})
public void operatorsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.operators);
}
@SuppressWarnings({"UnusedDeclaration"})
public void varsButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.vars);
}
@SuppressWarnings({"UnusedDeclaration"})
public void likeButtonClickHandler(@NotNull View v) {
buttonPressed(CalculatorSpecialButton.like);
}
}

View File

@@ -1,85 +1,138 @@
package org.solovyev.android.calculator;
import android.content.Context;
import android.content.Intent;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import jscl.math.Generic;
import jscl.math.function.Constant;
import org.achartengine.ChartFactory;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.about.CalculatorAboutActivity;
import org.solovyev.android.calculator.help.CalculatorHelpActivity;
import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotFragment;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils;
/**
* User: serso
* Date: 11/2/11
* Time: 2:18 PM
*/
public class CalculatorActivityLauncher {
public static void showHistory(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorHistoryActivity.class));
}
public static void showHelp(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorHelpActivity.class));
}
public static void showSettings(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorPreferencesActivity.class));
}
public static void showAbout(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorAboutActivity.class));
}
public static void showFunctions(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorFunctionsActivity.class));
}
public static void showOperators(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorOperatorsActivity.class));
}
public static void showVars(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorVarsActivity.class));
}
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);
}
}
}
package org.solovyev.android.calculator;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import jscl.math.Generic;
import jscl.math.function.Constant;
import org.achartengine.ChartFactory;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.about.CalculatorAboutActivity;
import org.solovyev.android.calculator.help.CalculatorHelpActivity;
import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotFragment;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils;
/**
* User: serso
* Date: 11/2/11
* Time: 2:18 PM
*/
public class CalculatorActivityLauncher {
public static void showHistory(@NotNull final Context context) {
showHistory(context, false);
}
public static void showHistory(@NotNull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorHistoryActivity.class);
addFlags(intent, detached);
context.startActivity(intent);
}
public static void showHelp(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorHelpActivity.class));
}
public static void showSettings(@NotNull final Context context) {
showSettings(context, false);
}
public static void showSettings(@NotNull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorPreferencesActivity.class);
addFlags(intent, detached);
context.startActivity(intent);
}
private static void addFlags(@NotNull Intent intent, boolean detached) {
int flags = Intent.FLAG_ACTIVITY_NEW_TASK;
if (detached) {
flags = flags | Intent.FLAG_ACTIVITY_NO_HISTORY;
}
intent.setFlags(flags);
}
public static void showAbout(@NotNull final Context context) {
context.startActivity(new Intent(context, CalculatorAboutActivity.class));
}
public static void showFunctions(@NotNull final Context context) {
showHistory(context, false);
}
public static void showFunctions(@NotNull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorFunctionsActivity.class);
addFlags(intent, detached);
context.startActivity(intent);
}
public static void showOperators(@NotNull final Context context) {
showOperators(context, false);
}
public static void showOperators(@NotNull final Context context, boolean detached) {
final Intent intent = new Intent(context, CalculatorOperatorsActivity.class);
addFlags(intent, detached);
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;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import net.robotmedia.billing.BillingController;
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.calculator.history.AndroidCalculatorHistory;
import org.solovyev.android.calculator.model.AndroidCalculatorEngine;
import org.solovyev.android.calculator.widget.CalculatorWidgetHelper;
/**
* 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 AD_FREE_PRODUCT_ID = "ad_free";
@@ -49,6 +48,9 @@ public class CalculatorApplication extends android.app.Application {
@NotNull
private static CalculatorApplication instance;
@NotNull
private CalculatorWidgetHelper widgetHelper;
/*
**********************************************************************
*
@@ -91,6 +93,10 @@ public class CalculatorApplication extends android.app.Application {
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() {
@Override
@@ -115,6 +121,9 @@ public class CalculatorApplication extends android.app.Application {
AdsController.getInstance().isAdFree(CalculatorApplication.this);
}
}).start();
CalculatorLocatorImpl.getInstance().getLogger().debug(TAG, "Application started!");
CalculatorLocatorImpl.getInstance().getNotifier().showDebugMessage(TAG, "Application started!");
}
private void setTheme(@NotNull SharedPreferences preferences) {
@@ -154,7 +163,4 @@ public class CalculatorApplication extends android.app.Application {
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,11 +0,0 @@
package org.solovyev.android.calculator.widget;
/**
* User: Solovyev_S
* Date: 19.10.12
* Time: 18:09
*/
public class CalculatorWidgetController {
public static final String BUTTON_PRESSED_ACTION = "org.solovyev.calculator.widget.BUTTON_PRESSED";
}

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

@@ -1,46 +1,199 @@
package org.solovyev.android.calculator.widget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.CalculatorApplication;
import org.solovyev.android.calculator.R;
/**
* User: Solovyev_S
* Date: 19.10.12
* Time: 16:18
*/
public class CalculatorWidgetProvider extends AppWidgetProvider {
public static final String BUTTON_PRESSED = "org.solovyev.calculator.widget.BUTTON_PRESSED";
@Override
public void onUpdate(@NotNull Context context,
@NotNull AppWidgetManager appWidgetManager,
@NotNull int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
final Intent onButtonClickIntent = new Intent(context, CalculatorWidgetProvider.class);
onButtonClickIntent.setAction(CalculatorWidgetController.BUTTON_PRESSED_ACTION);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, onButtonClickIntent, 0);
views.setOnClickPendingIntent(R.id.oneDigitButton, pendingIntent);
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if ( BUTTON_PRESSED.equals(intent.getAction()) ) {
Toast.makeText(CalculatorApplication.getInstance(), "Button pressed!", Toast.LENGTH_SHORT).show();
}
}
}
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;
}
}