Plotter
This commit is contained in:
parent
4070de7693
commit
f7b66673a5
@ -28,7 +28,11 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import dagger.Lazy;
|
||||||
|
import jscl.math.Generic;
|
||||||
|
import jscl.math.function.Constant;
|
||||||
|
import jscl.math.function.CustomFunction;
|
||||||
import org.solovyev.android.Activities;
|
import org.solovyev.android.Activities;
|
||||||
import org.solovyev.android.Check;
|
import org.solovyev.android.Check;
|
||||||
import org.solovyev.android.calculator.about.AboutActivity;
|
import org.solovyev.android.calculator.about.AboutActivity;
|
||||||
@ -38,31 +42,40 @@ import org.solovyev.android.calculator.functions.FunctionsActivity;
|
|||||||
import org.solovyev.android.calculator.history.HistoryActivity;
|
import org.solovyev.android.calculator.history.HistoryActivity;
|
||||||
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
|
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
|
||||||
import org.solovyev.android.calculator.operators.OperatorsActivity;
|
import org.solovyev.android.calculator.operators.OperatorsActivity;
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
import org.solovyev.android.calculator.plot.ExpressionFunction;
|
||||||
import org.solovyev.android.calculator.plot.PlotActivity;
|
import org.solovyev.android.calculator.plot.PlotActivity;
|
||||||
import org.solovyev.android.calculator.preferences.PreferencesActivity;
|
import org.solovyev.android.calculator.preferences.PreferencesActivity;
|
||||||
import org.solovyev.android.calculator.variables.CppVariable;
|
import org.solovyev.android.calculator.variables.CppVariable;
|
||||||
import org.solovyev.android.calculator.variables.EditVariableFragment;
|
import org.solovyev.android.calculator.variables.EditVariableFragment;
|
||||||
import org.solovyev.android.calculator.variables.VariablesActivity;
|
import org.solovyev.android.calculator.variables.VariablesActivity;
|
||||||
import org.solovyev.android.calculator.variables.VariablesFragment;
|
import org.solovyev.android.calculator.variables.VariablesFragment;
|
||||||
|
import org.solovyev.android.plotter.Plotter;
|
||||||
import org.solovyev.common.msg.MessageType;
|
import org.solovyev.common.msg.MessageType;
|
||||||
import org.solovyev.common.text.Strings;
|
import org.solovyev.common.text.Strings;
|
||||||
|
|
||||||
import jscl.math.Generic;
|
|
||||||
import jscl.math.function.Constant;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public final class ActivityLauncher implements CalculatorEventListener {
|
public final class ActivityLauncher implements CalculatorEventListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Application application;
|
Application application;
|
||||||
|
@Inject
|
||||||
|
Lazy<Plotter> plotter;
|
||||||
|
@Inject
|
||||||
|
Lazy<ErrorReporter> errorReporter;
|
||||||
|
@Inject
|
||||||
|
Lazy<Display> display;
|
||||||
|
@Inject
|
||||||
|
Lazy<VariablesRegistry> variablesRegistry;
|
||||||
|
@Inject
|
||||||
|
Notifier notifier;
|
||||||
@Nullable
|
@Nullable
|
||||||
private CalculatorActivity activity;
|
private CalculatorActivity activity;
|
||||||
|
|
||||||
@ -109,7 +122,7 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
|||||||
final CppFunction.Builder builder = CppFunction.builder("", functionBody);
|
final CppFunction.Builder builder = CppFunction.builder("", functionBody);
|
||||||
final Generic generic = viewState.getResult();
|
final Generic generic = viewState.getResult();
|
||||||
if (generic != null) {
|
if (generic != null) {
|
||||||
final Set<Constant> constants = CalculatorUtils.getNotSystemConstants(generic);
|
final Set<Constant> constants = generic.getUndefinedConstants(null);
|
||||||
for (Constant constant : constants) {
|
for (Constant constant : constants) {
|
||||||
builder.withParameter(constant.getName());
|
builder.withParameter(constant.getName());
|
||||||
}
|
}
|
||||||
@ -128,26 +141,13 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
|||||||
return ((CalculatorApplication) App.getApplication()).notifier;
|
return ((CalculatorApplication) App.getApplication()).notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tryPlot() {
|
public void plotDisplayedExpression() {
|
||||||
final CalculatorPlotter plotter = Locator.getInstance().getPlotter();
|
final DisplayState state = display.get().getState();
|
||||||
final Display display = App.getDisplay();
|
if (!state.valid) {
|
||||||
final DisplayState viewState = display.getState();
|
|
||||||
|
|
||||||
if (viewState.valid) {
|
|
||||||
final String functionValue = viewState.text;
|
|
||||||
final Generic expression = viewState.getResult();
|
|
||||||
if (!Strings.isEmpty(functionValue) && expression != null) {
|
|
||||||
if (plotter.isPlotPossibleFor(expression)) {
|
|
||||||
plotter.plot(expression);
|
|
||||||
} else {
|
|
||||||
getNotifier().showMessage(R.string.cpp_plot_too_many_variables, MessageType.error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getNotifier().showMessage(R.string.cpp_plot_empty_function_error, MessageType.error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
|
getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
plot(state.getResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showHistory() {
|
public void showHistory() {
|
||||||
@ -258,4 +258,44 @@ public final class ActivityLauncher implements CalculatorEventListener {
|
|||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plot(@Nullable Generic expression) {
|
||||||
|
if (expression == null) {
|
||||||
|
notifier.showMessage(R.string.cpp_plot_empty_function_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final String content = expression.toString();
|
||||||
|
if (TextUtils.isEmpty(content)) {
|
||||||
|
notifier.showMessage(R.string.cpp_plot_empty_function_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final List<String> parameters = new ArrayList<>();
|
||||||
|
for (Constant parameter : expression.getUndefinedConstants(variablesRegistry.get())) {
|
||||||
|
parameters.add(parameter.getName());
|
||||||
|
}
|
||||||
|
if (parameters.size() > 2) {
|
||||||
|
notifier.showMessage(R.string.cpp_plot_too_many_variables);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final CustomFunction f = new CustomFunction.Builder().setName("").setParameterNames(parameters).setContent(content).create();
|
||||||
|
final ExpressionFunction ef = new ExpressionFunction(f, false);
|
||||||
|
plotter.get().add(ef);
|
||||||
|
showPlotter();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
errorReporter.get().onException(e);
|
||||||
|
notifier.showMessage(e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canPlot(@Nullable Generic expression) {
|
||||||
|
if (expression == null || TextUtils.isEmpty(expression.toString())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (expression.getUndefinedConstants(variablesRegistry.get()).size() > 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,8 @@ import android.os.Handler;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TimingLogger;
|
import android.util.TimingLogger;
|
||||||
|
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
|
import jscl.MathEngine;
|
||||||
import org.acra.ACRA;
|
import org.acra.ACRA;
|
||||||
import org.acra.ACRAConfiguration;
|
import org.acra.ACRAConfiguration;
|
||||||
import org.acra.sender.HttpSender;
|
import org.acra.sender.HttpSender;
|
||||||
@ -38,18 +37,13 @@ import org.solovyev.android.calculator.floating.FloatingCalculatorActivity;
|
|||||||
import org.solovyev.android.calculator.history.History;
|
import org.solovyev.android.calculator.history.History;
|
||||||
import org.solovyev.android.calculator.language.Language;
|
import org.solovyev.android.calculator.language.Language;
|
||||||
import org.solovyev.android.calculator.language.Languages;
|
import org.solovyev.android.calculator.language.Languages;
|
||||||
import org.solovyev.android.calculator.plot.AndroidCalculatorPlotter;
|
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotterImpl;
|
|
||||||
import org.solovyev.common.msg.MessageType;
|
import org.solovyev.common.msg.MessageType;
|
||||||
|
|
||||||
import jscl.MathEngine;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class CalculatorApplication extends android.app.Application implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
@ -143,11 +137,7 @@ public class CalculatorApplication extends android.app.Application implements Sh
|
|||||||
languages.updateContextLocale(this, true);
|
languages.updateContextLocale(this, true);
|
||||||
App.getGa().reportInitially(preferences);
|
App.getGa().reportInitially(preferences);
|
||||||
|
|
||||||
Locator.getInstance().init(calculator,
|
Locator.getInstance().init(calculator, engine, keyboard);
|
||||||
engine,
|
|
||||||
keyboard,
|
|
||||||
new AndroidCalculatorPlotter(this, new CalculatorPlotterImpl(calculator))
|
|
||||||
);
|
|
||||||
|
|
||||||
calculator.init(initThread);
|
calculator.init(initThread);
|
||||||
|
|
||||||
|
@ -22,16 +22,13 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public interface CalculatorLocator {
|
public interface CalculatorLocator {
|
||||||
|
|
||||||
void init(@Nonnull Calculator calculator,
|
void init(@Nonnull Calculator calculator,
|
||||||
@Nonnull Engine engine,
|
@Nonnull Engine engine,
|
||||||
@Nonnull Keyboard keyboard,
|
@Nonnull Keyboard keyboard);
|
||||||
@Nonnull CalculatorPlotter plotter);
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Calculator getCalculator();
|
Calculator getCalculator();
|
||||||
@ -42,6 +39,4 @@ public interface CalculatorLocator {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
Keyboard getKeyboard();
|
Keyboard getKeyboard();
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
CalculatorPlotter getPlotter();
|
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,6 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import jscl.math.Generic;
|
|
||||||
import jscl.math.function.Constant;
|
|
||||||
import jscl.math.function.IConstant;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
* Date: 9/22/12
|
* Date: 9/22/12
|
||||||
@ -42,18 +33,4 @@ public final class CalculatorUtils {
|
|||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static Set<Constant> getNotSystemConstants(@Nonnull Generic expression) {
|
|
||||||
final Set<Constant> notSystemConstants = new HashSet<Constant>();
|
|
||||||
|
|
||||||
for (Constant constant : expression.getConstants()) {
|
|
||||||
IConstant var = Locator.getInstance().getEngine().getVariablesRegistry().get(constant.getName());
|
|
||||||
if (var != null && !var.isSystem() && !var.isDefined()) {
|
|
||||||
notSystemConstants.add(constant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return notSystemConstants;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,6 @@ public class Display {
|
|||||||
Lazy<Notifier> notifier;
|
Lazy<Notifier> notifier;
|
||||||
@Inject
|
@Inject
|
||||||
Lazy<PreferredPreferences> preferredPreferences;
|
Lazy<PreferredPreferences> preferredPreferences;
|
||||||
@Inject
|
|
||||||
ActivityLauncher launcher;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private DisplayView view;
|
private DisplayView view;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -37,17 +37,12 @@ import butterknife.ButterKnife;
|
|||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
import jscl.NumeralBase;
|
import jscl.NumeralBase;
|
||||||
import jscl.math.Generic;
|
import jscl.math.Generic;
|
||||||
import jscl.math.function.Constant;
|
|
||||||
import jscl.math.function.CustomFunction;
|
|
||||||
import org.solovyev.android.calculator.converter.ConverterFragment;
|
import org.solovyev.android.calculator.converter.ConverterFragment;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
import org.solovyev.android.calculator.plot.ExpressionFunction;
|
|
||||||
import org.solovyev.android.plotter.Plotter;
|
import org.solovyev.android.plotter.Plotter;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DisplayFragment extends BaseFragment implements View.OnClickListener,
|
public class DisplayFragment extends BaseFragment implements View.OnClickListener,
|
||||||
MenuItem.OnMenuItemClickListener {
|
MenuItem.OnMenuItemClickListener {
|
||||||
@ -146,8 +141,7 @@ public class DisplayFragment extends BaseFragment implements View.OnClickListene
|
|||||||
addMenu(menu, R.string.c_convert, this);
|
addMenu(menu, R.string.c_convert, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final int parameters = CalculatorUtils.getNotSystemConstants(result).size();
|
if (launcher.canPlot(result)) {
|
||||||
if (parameters >= 0 && parameters <= 2) {
|
|
||||||
addMenu(menu, R.string.c_plot, this);
|
addMenu(menu, R.string.c_plot, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,21 +210,7 @@ public class DisplayFragment extends BaseFragment implements View.OnClickListene
|
|||||||
ConverterFragment.show(getActivity(), getValue(result));
|
ConverterFragment.show(getActivity(), getValue(result));
|
||||||
return true;
|
return true;
|
||||||
case R.string.c_plot:
|
case R.string.c_plot:
|
||||||
if (result != null) {
|
launcher.plot(result);
|
||||||
try {
|
|
||||||
final List<String> parameters = new ArrayList<>();
|
|
||||||
for (Constant parameter : CalculatorUtils.getNotSystemConstants(result)) {
|
|
||||||
parameters.add(parameter.getName());
|
|
||||||
}
|
|
||||||
new CustomFunction.Builder().setParameterNames(parameters).setContent(state.text).create();
|
|
||||||
final CustomFunction f = new CustomFunction.Builder().setName("").setParameterNames(parameters).setContent(result.toString()).create();
|
|
||||||
final ExpressionFunction ef = new ExpressionFunction(f, false);
|
|
||||||
plotter.add(ef);
|
|
||||||
launcher.showPlotter();
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
errorReporter.onException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class Locator implements CalculatorLocator {
|
public class Locator implements CalculatorLocator {
|
||||||
@ -36,8 +34,6 @@ public class Locator implements CalculatorLocator {
|
|||||||
private Calculator calculator;
|
private Calculator calculator;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private Keyboard keyboard;
|
private Keyboard keyboard;
|
||||||
@Nonnull
|
|
||||||
private CalculatorPlotter calculatorPlotter;
|
|
||||||
|
|
||||||
public Locator() {
|
public Locator() {
|
||||||
}
|
}
|
||||||
@ -50,13 +46,10 @@ public class Locator implements CalculatorLocator {
|
|||||||
@Override
|
@Override
|
||||||
public void init(@Nonnull Calculator calculator,
|
public void init(@Nonnull Calculator calculator,
|
||||||
@Nonnull Engine engine,
|
@Nonnull Engine engine,
|
||||||
@Nonnull Keyboard keyboard,
|
@Nonnull Keyboard keyboard) {
|
||||||
@Nonnull CalculatorPlotter plotter) {
|
|
||||||
|
|
||||||
this.calculator = calculator;
|
this.calculator = calculator;
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
this.calculatorPlotter = plotter;
|
|
||||||
|
|
||||||
this.keyboard = keyboard;
|
this.keyboard = keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,9 +71,4 @@ public class Locator implements CalculatorLocator {
|
|||||||
return keyboard;
|
return keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public CalculatorPlotter getPlotter() {
|
|
||||||
return calculatorPlotter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,14 @@ package org.solovyev.android.calculator;
|
|||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import org.solovyev.android.Threads;
|
import org.solovyev.android.Threads;
|
||||||
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 javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class Notifier {
|
public class Notifier {
|
||||||
@ -48,21 +45,22 @@ public class Notifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void showMessage(@Nonnull Message message) {
|
public void showMessage(@Nonnull Message message) {
|
||||||
showMessageInUiThread(message.getLocalizedMessage());
|
showMessage(message.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showMessage(@Nonnull Integer messageCode, @Nonnull MessageType messageType, @Nonnull List<Object> parameters) {
|
public void showMessage(@StringRes int message, Object... parameters) {
|
||||||
showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
|
showMessage(application.getString(message, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showMessage(@Nonnull Integer messageCode, @Nonnull MessageType messageType, @Nullable Object... parameters) {
|
public void showMessage(@StringRes int message) {
|
||||||
showMessage(new AndroidMessage(messageCode, messageType, application, parameters));
|
showMessage(application.getString(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showMessageInUiThread(@Nonnull final String message) {
|
public void showMessage(@Nonnull final String message) {
|
||||||
if (Threads.isUiThread()) {
|
if (Threads.isUiThread()) {
|
||||||
Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(application, message, Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
handler.post(new Runnable() {
|
handler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -71,4 +69,3 @@ public class Notifier {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
package org.solovyev.android.calculator.keyboard;
|
package org.solovyev.android.calculator.keyboard;
|
||||||
|
|
||||||
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING;
|
|
||||||
import static android.view.HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING;
|
|
||||||
import static android.view.HapticFeedbackConstants.KEYBOARD_TAP;
|
|
||||||
import static org.solovyev.android.calculator.App.cast;
|
|
||||||
import static org.solovyev.android.calculator.App.getScreenMetrics;
|
|
||||||
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple;
|
|
||||||
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -20,15 +12,8 @@ import android.util.TypedValue;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.solovyev.android.Views;
|
import org.solovyev.android.Views;
|
||||||
import org.solovyev.android.calculator.ActivityUi;
|
import org.solovyev.android.calculator.*;
|
||||||
import org.solovyev.android.calculator.App;
|
|
||||||
import org.solovyev.android.calculator.Calculator;
|
|
||||||
import org.solovyev.android.calculator.Editor;
|
|
||||||
import org.solovyev.android.calculator.Keyboard;
|
|
||||||
import org.solovyev.android.calculator.Preferences;
|
|
||||||
import org.solovyev.android.calculator.PreferredPreferences;
|
|
||||||
import org.solovyev.android.calculator.buttons.CppSpecialButton;
|
import org.solovyev.android.calculator.buttons.CppSpecialButton;
|
||||||
import org.solovyev.android.calculator.view.ScreenMetrics;
|
import org.solovyev.android.calculator.view.ScreenMetrics;
|
||||||
import org.solovyev.android.views.Adjuster;
|
import org.solovyev.android.views.Adjuster;
|
||||||
@ -37,11 +22,16 @@ import org.solovyev.android.views.dragbutton.DragButton;
|
|||||||
import org.solovyev.android.views.dragbutton.DragDirection;
|
import org.solovyev.android.views.dragbutton.DragDirection;
|
||||||
import org.solovyev.android.views.dragbutton.SimpleDragListener;
|
import org.solovyev.android.views.dragbutton.SimpleDragListener;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.inject.Inject;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import static android.view.HapticFeedbackConstants.*;
|
||||||
import javax.inject.Inject;
|
import static org.solovyev.android.calculator.App.cast;
|
||||||
|
import static org.solovyev.android.calculator.App.getScreenMetrics;
|
||||||
|
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple;
|
||||||
|
import static org.solovyev.android.calculator.Preferences.Gui.Layout.simple_mobile;
|
||||||
|
|
||||||
public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, SimpleDragListener.DragProcessor, View.OnClickListener {
|
public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPreferenceChangeListener, SimpleDragListener.DragProcessor, View.OnClickListener {
|
||||||
|
|
||||||
@ -67,6 +57,8 @@ public abstract class BaseKeyboardUi implements SharedPreferences.OnSharedPrefer
|
|||||||
@Inject
|
@Inject
|
||||||
Calculator calculator;
|
Calculator calculator;
|
||||||
@Inject
|
@Inject
|
||||||
|
ActivityLauncher launcher;
|
||||||
|
@Inject
|
||||||
PreferredPreferences preferredPreferences;
|
PreferredPreferences preferredPreferences;
|
||||||
protected int orientation = Configuration.ORIENTATION_PORTRAIT;
|
protected int orientation = Configuration.ORIENTATION_PORTRAIT;
|
||||||
private int textSize;
|
private int textSize;
|
||||||
|
@ -17,7 +17,6 @@ import butterknife.Bind;
|
|||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import jscl.NumeralBase;
|
import jscl.NumeralBase;
|
||||||
import org.solovyev.android.Check;
|
import org.solovyev.android.Check;
|
||||||
import org.solovyev.android.calculator.ActivityLauncher;
|
|
||||||
import org.solovyev.android.calculator.Engine;
|
import org.solovyev.android.calculator.Engine;
|
||||||
import org.solovyev.android.calculator.Preferences;
|
import org.solovyev.android.calculator.Preferences;
|
||||||
import org.solovyev.android.calculator.R;
|
import org.solovyev.android.calculator.R;
|
||||||
@ -121,7 +120,7 @@ public class PartialKeyboardUi extends BaseKeyboardUi {
|
|||||||
return true;
|
return true;
|
||||||
case R.id.cpp_button_equals:
|
case R.id.cpp_button_equals:
|
||||||
if (direction == down) {
|
if (direction == down) {
|
||||||
ActivityLauncher.tryPlot();
|
launcher.plotDisplayedExpression();
|
||||||
return true;
|
return true;
|
||||||
} else if (direction == up) {
|
} else if (direction == up) {
|
||||||
calculator.simplify();
|
calculator.simplify();
|
||||||
|
@ -1,442 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator.plot;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import jscl.math.Generic;
|
|
||||||
import jscl.math.function.Constant;
|
|
||||||
import org.solovyev.android.calculator.Calculator;
|
|
||||||
import org.solovyev.android.calculator.CalculatorEventType;
|
|
||||||
import org.solovyev.android.calculator.CalculatorUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CalculatorPlotterImpl implements CalculatorPlotter {
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private final List<PlotFunction> functions = new ArrayList<PlotFunction>();
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private final Calculator calculator;
|
|
||||||
|
|
||||||
private final PlotResourceManager resourceManager = new MapPlotResourceManager();
|
|
||||||
|
|
||||||
private boolean plot3d = false;
|
|
||||||
private boolean adjustYAxis = true;
|
|
||||||
|
|
||||||
private boolean plotImag = false;
|
|
||||||
|
|
||||||
private int arity = 0;
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private PlotBoundaries plotBoundaries = PlotBoundaries.newDefaultInstance();
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private PlotData plotData = new PlotData(Collections.<PlotFunction>emptyList(), plot3d, true, plotBoundaries);
|
|
||||||
|
|
||||||
public CalculatorPlotterImpl(@Nonnull Calculator calculator) {
|
|
||||||
this.calculator = calculator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public PlotData getPlotData() {
|
|
||||||
return plotData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addFunction(@Nonnull Generic expression) {
|
|
||||||
final List<Constant> variables = new ArrayList<Constant>(CalculatorUtils.getNotSystemConstants(expression));
|
|
||||||
|
|
||||||
if (variables.size() > 2) throw new AssertionError();
|
|
||||||
|
|
||||||
final Constant xVariable;
|
|
||||||
if (variables.size() > 0) {
|
|
||||||
xVariable = variables.get(0);
|
|
||||||
} else {
|
|
||||||
xVariable = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Constant yVariable;
|
|
||||||
if (variables.size() > 1) {
|
|
||||||
yVariable = variables.get(1);
|
|
||||||
} else {
|
|
||||||
yVariable = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final XyFunction realXyFunction = new XyFunction(expression, xVariable, yVariable, false);
|
|
||||||
final XyFunction imagXyFunction = new XyFunction(expression, xVariable, yVariable, true);
|
|
||||||
|
|
||||||
// first create plot functions with default line definitions
|
|
||||||
PlotFunction realPlotFunction = new PlotFunction(realXyFunction);
|
|
||||||
PlotFunction imagPlotFunction = new PlotFunction(imagXyFunction);
|
|
||||||
|
|
||||||
// then remove all unpinned graphs and free their line definitions
|
|
||||||
removeAllUnpinnedExcept(realPlotFunction, imagPlotFunction);
|
|
||||||
|
|
||||||
// create plot functions with freed line definitions
|
|
||||||
realPlotFunction = newPlotFunction(realXyFunction);
|
|
||||||
imagPlotFunction = newPlotFunction(imagXyFunction);
|
|
||||||
|
|
||||||
final boolean realAdded = addFunction(realPlotFunction);
|
|
||||||
final boolean imagAdded = addFunction(plotImag ? imagPlotFunction : PlotFunction.invisible(imagPlotFunction));
|
|
||||||
|
|
||||||
return imagAdded || realAdded;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private PlotFunction newPlotFunction(@Nonnull XyFunction xyFunction) {
|
|
||||||
return new PlotFunction(xyFunction, resourceManager.generateAndRegister());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addFunction(@Nonnull PlotFunction plotFunction) {
|
|
||||||
synchronized (functions) {
|
|
||||||
if (!functions.contains(plotFunction)) {
|
|
||||||
resourceManager.register(plotFunction.getPlotLineDef());
|
|
||||||
functions.add(plotFunction);
|
|
||||||
onFunctionsChanged();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean removeAllUnpinnedExcept(@Nonnull final PlotFunction... exceptFunctions) {
|
|
||||||
synchronized (functions) {
|
|
||||||
|
|
||||||
boolean changed = Iterables.removeIf(functions, new Predicate<PlotFunction>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(@Nullable PlotFunction function) {
|
|
||||||
if (function != null && !function.isPinned()) {
|
|
||||||
|
|
||||||
for (PlotFunction exceptFunction : exceptFunctions) {
|
|
||||||
if (exceptFunction.equals(function)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceManager.unregister(function.getPlotLineDef());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
onFunctionsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeAllUnpinned() {
|
|
||||||
synchronized (functions) {
|
|
||||||
boolean changed = Iterables.removeIf(functions, new Predicate<PlotFunction>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(@Nullable PlotFunction function) {
|
|
||||||
boolean removed = function != null && !function.isPinned();
|
|
||||||
|
|
||||||
if (removed) {
|
|
||||||
resourceManager.unregister(function.getPlotLineDef());
|
|
||||||
}
|
|
||||||
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
onFunctionsChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeFunction(@Nonnull PlotFunction plotFunction) {
|
|
||||||
synchronized (functions) {
|
|
||||||
boolean changed = functions.remove(plotFunction);
|
|
||||||
if (changed) {
|
|
||||||
resourceManager.unregister(plotFunction.getPlotLineDef());
|
|
||||||
onFunctionsChanged();
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addFunction(@Nonnull XyFunction xyFunction) {
|
|
||||||
return addFunction(newPlotFunction(xyFunction));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addFunction(@Nonnull XyFunction xyFunction, @Nonnull PlotLineDef functionLineDef) {
|
|
||||||
return addFunction(new PlotFunction(xyFunction, functionLineDef));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean updateFunction(@Nonnull XyFunction xyFunction, @Nonnull PlotLineDef functionLineDef) {
|
|
||||||
final PlotFunction newFunction = new PlotFunction(xyFunction, functionLineDef);
|
|
||||||
|
|
||||||
return updateFunction(newFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean updateFunction(@Nonnull PlotFunction newFunction) {
|
|
||||||
boolean changed = updateFunction0(newFunction);
|
|
||||||
if (changed) {
|
|
||||||
firePlotDataChangedEvent();
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean updateFunction0(@Nonnull PlotFunction newFunction) {
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
synchronized (functions) {
|
|
||||||
for (int i = 0; i < functions.size(); i++) {
|
|
||||||
final PlotFunction oldFunction = functions.get(i);
|
|
||||||
if (oldFunction.equals(newFunction)) {
|
|
||||||
|
|
||||||
resourceManager.unregister(oldFunction.getPlotLineDef());
|
|
||||||
resourceManager.register(newFunction.getPlotLineDef());
|
|
||||||
|
|
||||||
// update old function
|
|
||||||
functions.set(i, newFunction);
|
|
||||||
changed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeFunction(@Nonnull XyFunction xyFunction) {
|
|
||||||
return removeFunction(new PlotFunction(xyFunction));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public PlotFunction pin(@Nonnull PlotFunction plotFunction) {
|
|
||||||
final PlotFunction newFunction = PlotFunction.pin(plotFunction);
|
|
||||||
updateFunction0(newFunction);
|
|
||||||
return newFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public PlotFunction unpin(@Nonnull PlotFunction plotFunction) {
|
|
||||||
final PlotFunction newFunction = PlotFunction.unpin(plotFunction);
|
|
||||||
updateFunction0(newFunction);
|
|
||||||
return newFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public PlotFunction show(@Nonnull PlotFunction plotFunction) {
|
|
||||||
final PlotFunction newFunction = PlotFunction.visible(plotFunction);
|
|
||||||
|
|
||||||
updateFunction(newFunction);
|
|
||||||
|
|
||||||
return newFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public PlotFunction hide(@Nonnull PlotFunction plotFunction) {
|
|
||||||
final PlotFunction newFunction = PlotFunction.invisible(plotFunction);
|
|
||||||
|
|
||||||
updateFunction(newFunction);
|
|
||||||
|
|
||||||
return newFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearAllFunctions() {
|
|
||||||
synchronized (functions) {
|
|
||||||
resourceManager.unregisterAll();
|
|
||||||
functions.clear();
|
|
||||||
onFunctionsChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public PlotFunction getFunctionById(@Nonnull final String functionId) {
|
|
||||||
synchronized (functions) {
|
|
||||||
return Iterables.find(functions, new Predicate<PlotFunction>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(@Nullable PlotFunction function) {
|
|
||||||
return function != null && function.getXyFunction().getId().equals(functionId);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: this method must be called from synchronized block
|
|
||||||
private void onFunctionsChanged() {
|
|
||||||
if (!Thread.holdsLock(functions)) throw new AssertionError();
|
|
||||||
|
|
||||||
int maxArity = 0;
|
|
||||||
for (PlotFunction function : functions) {
|
|
||||||
final XyFunction xyFunction = function.getXyFunction();
|
|
||||||
|
|
||||||
maxArity = Math.max(maxArity, xyFunction.getArity());
|
|
||||||
}
|
|
||||||
|
|
||||||
plot3d = maxArity > 1;
|
|
||||||
|
|
||||||
if (functions.isEmpty()) {
|
|
||||||
// no functions => new plot => default boundaries
|
|
||||||
this.plotBoundaries = PlotBoundaries.newDefaultInstance();
|
|
||||||
this.adjustYAxis = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
arity = maxArity;
|
|
||||||
|
|
||||||
firePlotDataChangedEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public List<PlotFunction> getFunctions() {
|
|
||||||
synchronized (functions) {
|
|
||||||
return new ArrayList<PlotFunction>(functions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public List<PlotFunction> getVisibleFunctions() {
|
|
||||||
synchronized (functions) {
|
|
||||||
return Lists.newArrayList(Iterables.filter(functions, new Predicate<PlotFunction>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(@Nullable PlotFunction function) {
|
|
||||||
return function != null && function.isVisible();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void plot() {
|
|
||||||
calculator.fireCalculatorEvent(CalculatorEventType.plot_graph, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void plot(@Nonnull Generic expression) {
|
|
||||||
addFunction(expression);
|
|
||||||
plot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean is2dPlotPossible() {
|
|
||||||
return arity < 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPlotPossibleFor(@Nonnull Generic expression) {
|
|
||||||
boolean result = false;
|
|
||||||
|
|
||||||
int size = CalculatorUtils.getNotSystemConstants(expression).size();
|
|
||||||
if (size == 0 || size == 1 || size == 2) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlot3d(boolean plot3d) {
|
|
||||||
if (this.plot3d != plot3d) {
|
|
||||||
this.plot3d = plot3d;
|
|
||||||
firePlotDataChangedEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void firePlotDataChangedEvent() {
|
|
||||||
updatePlotData();
|
|
||||||
calculator.fireCalculatorEvent(CalculatorEventType.plot_data_changed, plotData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePlotData() {
|
|
||||||
plotData = new PlotData(getVisibleFunctions(), plot3d, adjustYAxis, plotBoundaries);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlotImag(boolean plotImag) {
|
|
||||||
if (this.plotImag != plotImag) {
|
|
||||||
this.plotImag = plotImag;
|
|
||||||
if (toggleImagFunctions(this.plotImag)) {
|
|
||||||
firePlotDataChangedEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void savePlotBoundaries(@Nonnull PlotBoundaries plotBoundaries) {
|
|
||||||
if (!this.plotBoundaries.equals(plotBoundaries)) {
|
|
||||||
this.plotBoundaries = plotBoundaries;
|
|
||||||
this.adjustYAxis = false;
|
|
||||||
updatePlotData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlotBoundaries(@Nonnull PlotBoundaries plotBoundaries) {
|
|
||||||
if (!this.plotBoundaries.equals(plotBoundaries)) {
|
|
||||||
this.plotBoundaries = plotBoundaries;
|
|
||||||
this.adjustYAxis = false;
|
|
||||||
firePlotDataChangedEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean toggleImagFunctions(boolean show) {
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
synchronized (functions) {
|
|
||||||
for (int i = 0; i < functions.size(); i++) {
|
|
||||||
final PlotFunction plotFunction = functions.get(i);
|
|
||||||
if (plotFunction.getXyFunction().isImag()) {
|
|
||||||
functions.set(i, show ? PlotFunction.visible(plotFunction) : PlotFunction.invisible(plotFunction));
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 serso aka se.solovyev
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
* Contact details
|
|
||||||
*
|
|
||||||
* Email: se.solovyev@gmail.com
|
|
||||||
* Site: http://se.solovyev.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.android.calculator.plot;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.solovyev.android.calculator.Locator;
|
|
||||||
import org.solovyev.android.calculator.R;
|
|
||||||
import org.solovyev.android.list.ListItem;
|
|
||||||
import org.solovyev.android.view.ViewBuilder;
|
|
||||||
import org.solovyev.android.view.ViewFromLayoutBuilder;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public class PlotFunctionListItem implements ListItem {
|
|
||||||
|
|
||||||
private static final String PREFIX = "plot_function_";
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private PlotFunction plotFunction;
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private ViewBuilder<View> viewBuilder;
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private String tag;
|
|
||||||
|
|
||||||
public PlotFunctionListItem(@Nonnull PlotFunction plotFunction) {
|
|
||||||
this.plotFunction = plotFunction;
|
|
||||||
this.viewBuilder = ViewFromLayoutBuilder.newInstance(R.layout.cpp_plot_function_list_item);
|
|
||||||
this.tag = PREFIX + plotFunction.getXyFunction().getExpressionString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public OnClickAction getOnClickAction() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public OnClickAction getOnLongClickAction() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public View updateView(@Nonnull Context context, @Nonnull View view) {
|
|
||||||
final Object viewTag = view.getTag();
|
|
||||||
if (viewTag instanceof String) {
|
|
||||||
if (this.tag.equals(viewTag)) {
|
|
||||||
return view;
|
|
||||||
} else if (((String) viewTag).startsWith(PREFIX)) {
|
|
||||||
fillView(view, context);
|
|
||||||
return view;
|
|
||||||
} else {
|
|
||||||
return build(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return build(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public View build(@Nonnull Context context) {
|
|
||||||
final View root = buildView(context);
|
|
||||||
fillView(root, context);
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
private View buildView(@Nonnull Context context) {
|
|
||||||
return viewBuilder.build(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fillView(@Nonnull View root, @Nonnull final Context context) {
|
|
||||||
root.setTag(tag);
|
|
||||||
|
|
||||||
final CalculatorPlotter plotter = Locator.getInstance().getPlotter();
|
|
||||||
|
|
||||||
final TextView expressionTextView = (TextView) root.findViewById(R.id.cpp_plot_function_expression_textview);
|
|
||||||
expressionTextView.setText(plotFunction.getXyFunction().getExpressionString());
|
|
||||||
|
|
||||||
final CheckBox pinnedCheckBox = (CheckBox) root.findViewById(R.id.cpp_plot_function_pinned_checkbox);
|
|
||||||
pinnedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean pin) {
|
|
||||||
if (pin) {
|
|
||||||
if (!plotFunction.isPinned()) {
|
|
||||||
plotFunction = plotter.pin(plotFunction);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (plotFunction.isPinned()) {
|
|
||||||
plotFunction = plotter.unpin(plotFunction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pinnedCheckBox.setChecked(plotFunction.isPinned());
|
|
||||||
|
|
||||||
final CheckBox visibleCheckBox = (CheckBox) root.findViewById(R.id.cpp_plot_function_visible_checkbox);
|
|
||||||
visibleCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean show) {
|
|
||||||
if (show) {
|
|
||||||
if (!plotFunction.isVisible()) {
|
|
||||||
plotFunction = plotter.show(plotFunction);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (plotFunction.isVisible()) {
|
|
||||||
plotFunction = plotter.hide(plotFunction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
visibleCheckBox.setChecked(plotFunction.isVisible());
|
|
||||||
|
|
||||||
final ImageButton settingsButton = (ImageButton) root.findViewById(R.id.cpp_plot_function_settings_button);
|
|
||||||
settingsButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
// FIXME: 2016-02-01
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,6 @@ package org.solovyev.android.calculator;
|
|||||||
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import com.squareup.otto.Bus;
|
import com.squareup.otto.Bus;
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ import static org.mockito.Mockito.mock;
|
|||||||
public class AbstractCalculatorTest {
|
public class AbstractCalculatorTest {
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), CalculatorTestUtils.newCalculatorEngine(), mock(Keyboard.class));
|
||||||
Locator.getInstance().getEngine().init(new Executor() {
|
Locator.getInstance().getEngine().init(new Executor() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
|
@ -36,7 +36,6 @@ import org.solovyev.android.calculator.jscl.JsclOperation;
|
|||||||
import org.solovyev.android.calculator.language.Languages;
|
import org.solovyev.android.calculator.language.Languages;
|
||||||
import org.solovyev.android.calculator.operators.OperatorsRegistry;
|
import org.solovyev.android.calculator.operators.OperatorsRegistry;
|
||||||
import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry;
|
import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry;
|
||||||
import org.solovyev.android.calculator.plot.CalculatorPlotter;
|
|
||||||
|
|
||||||
import jscl.JsclMathEngine;
|
import jscl.JsclMathEngine;
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ public class CalculatorTestUtils {
|
|||||||
|
|
||||||
public static void staticSetUp() throws Exception {
|
public static void staticSetUp() throws Exception {
|
||||||
App.init(new CalculatorApplication(), new Languages(new RoboSharedPreferences(new HashMap<String, Map<String, Object>>(), "test", 0)));
|
App.init(new CalculatorApplication(), new Languages(new RoboSharedPreferences(new HashMap<String, Map<String, Object>>(), "test", 0)));
|
||||||
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class));
|
||||||
Locator.getInstance().getEngine().init(new Executor() {
|
Locator.getInstance().getEngine().init(new Executor() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
@ -83,7 +82,7 @@ public class CalculatorTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void staticSetUp(@Nullable Context context) throws Exception {
|
public static void staticSetUp(@Nullable Context context) throws Exception {
|
||||||
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class), mock(CalculatorPlotter.class));
|
Locator.getInstance().init(new Calculator(mock(SharedPreferences.class), mock(Bus.class), mock(Executor.class), mock(Executor.class)), newCalculatorEngine(), mock(Keyboard.class));
|
||||||
Locator.getInstance().getEngine().init(new Executor() {
|
Locator.getInstance().getEngine().init(new Executor() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(Runnable command) {
|
public void execute(Runnable command) {
|
||||||
|
@ -1,17 +1,40 @@
|
|||||||
package jscl.math;
|
package jscl.math;
|
||||||
|
|
||||||
import jscl.math.function.Constant;
|
import jscl.math.function.Constant;
|
||||||
|
import jscl.math.function.IConstant;
|
||||||
import jscl.mathml.MathML;
|
import jscl.mathml.MathML;
|
||||||
import jscl.text.ParserUtils;
|
import jscl.text.ParserUtils;
|
||||||
|
import org.solovyev.common.math.MathRegistry;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public abstract class Generic implements Arithmetic<Generic>, Comparable {
|
public abstract class Generic implements Arithmetic<Generic>, Comparable {
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Set<Constant> getUndefinedConstants(@Nonnull MathRegistry<IConstant> constantsRegistry) {
|
||||||
|
final Set<Constant> result = new HashSet<>();
|
||||||
|
|
||||||
|
for (Constant expressionConstant : getConstants()) {
|
||||||
|
final IConstant registryConstant = constantsRegistry.get(expressionConstant.getName());
|
||||||
|
if (registryConstant == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (registryConstant.isSystem()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(registryConstant.isDefined()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.add(expressionConstant);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public BigInteger toBigInteger() {
|
public BigInteger toBigInteger() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class CustomFunction extends Function implements IFunction {
|
|||||||
private CustomFunction(@Nonnull String name,
|
private CustomFunction(@Nonnull String name,
|
||||||
@Nonnull List<String> parameterNames,
|
@Nonnull List<String> parameterNames,
|
||||||
@Nonnull String content,
|
@Nonnull String content,
|
||||||
@Nullable String description) {
|
@Nullable String description) throws CustomFunctionCalculationException {
|
||||||
super(name, new Generic[parameterNames.size()]);
|
super(name, new Generic[parameterNames.size()]);
|
||||||
this.parameterNames = parameterNames;
|
this.parameterNames = parameterNames;
|
||||||
try {
|
try {
|
||||||
@ -321,7 +321,7 @@ public class CustomFunction extends Function implements IFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public CustomFunction create() {
|
public CustomFunction create() throws CustomFunctionCalculationException {
|
||||||
final CustomFunction customFunction = new CustomFunction(name, parameterNames, prepareContent(content), description);
|
final CustomFunction customFunction = new CustomFunction(name, parameterNames, prepareContent(content), description);
|
||||||
customFunction.setSystem(system);
|
customFunction.setSystem(system);
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user