new plotter

This commit is contained in:
Sergey Solovyev 2013-01-19 16:53:09 +04:00
parent 2ebf5841e1
commit 4e6d49abf4
7 changed files with 78 additions and 30 deletions

View File

@ -310,6 +310,9 @@
<string name="cpp_function">Function</string> <string name="cpp_function">Function</string>
<string name="cpp_pinned">Pinned</string> <string name="cpp_pinned">Pinned</string>
<string name="cpp_visible">Visible</string> <string name="cpp_visible">Visible</string>
<string name="cpp_plot_button_text">+plot</string>
<string name="cpp_plot_empty_function_error">Unable to plot empty function!</string>
<string name="cpp_plot_too_many_variables">Unable to plot: too many variables!</string>
</resources> </resources>

View File

@ -11,6 +11,7 @@
a:id="@id/cpp_button_equals" a:id="@id/cpp_button_equals"
c:textUp="≡" c:textUp="≡"
a:text="=" a:text="="
c:textDown="@string/cpp_plot_button_text"
c:directionTextScale="0.5" c:directionTextScale="0.5"
a:layout_width="fill_parent" a:layout_width="fill_parent"
a:layout_height="fill_parent" a:layout_height="fill_parent"

View File

@ -120,7 +120,7 @@ public abstract class AbstractCalculatorHelper implements SharedPreferences.OnSh
final DragButton equalsButton = getButton(root, R.id.cpp_button_equals); final DragButton equalsButton = getButton(root, R.id.cpp_button_equals);
if (equalsButton != null) { if (equalsButton != null) {
equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EvalDragProcessor(), dragPreferences), vibrator, preferences)); equalsButton.setOnDragListener(new OnDragListenerVibrator(newOnDragListener(new EqualsDragProcessor(), dragPreferences), vibrator, preferences));
} }
final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) getButton(root, R.id.cpp_button_6); final AngleUnitsButton angleUnitsButton = (AngleUnitsButton) getButton(root, R.id.cpp_button_6);

View File

@ -11,6 +11,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils2; import org.solovyev.android.AndroidUtils2;
@ -22,6 +23,7 @@ import org.solovyev.android.calculator.history.CalculatorHistoryActivity;
import org.solovyev.android.calculator.math.edit.*; import org.solovyev.android.calculator.math.edit.*;
import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity; import org.solovyev.android.calculator.matrix.CalculatorMatrixActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotActivity; import org.solovyev.android.calculator.plot.CalculatorPlotActivity;
import org.solovyev.android.calculator.plot.CalculatorPlotter;
import org.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType; import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.text.StringUtils;
@ -102,8 +104,9 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
context.startActivity(intent); context.startActivity(intent);
} }
public static void createVar(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) { public static void tryCreateVar(@NotNull final Context context) {
final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState(); final CalculatorDisplay display = Locator.getInstance().getDisplay();
final CalculatorDisplayViewState viewState = display.getViewState();
if (viewState.isValid() ) { if (viewState.isValid() ) {
final String varValue = viewState.getText(); final String varValue = viewState.getText();
if (!StringUtils.isEmpty(varValue)) { if (!StringUtils.isEmpty(varValue)) {
@ -117,18 +120,19 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
context.startActivity(intent); context.startActivity(intent);
} }
} else { } else {
Locator.getInstance().getNotifier().showMessage(R.string.c_value_is_not_a_number, MessageType.error); getNotifier().showMessage(R.string.c_value_is_not_a_number, MessageType.error);
} }
} else { } else {
Locator.getInstance().getNotifier().showMessage(R.string.empty_var_error, MessageType.error); getNotifier().showMessage(R.string.empty_var_error, MessageType.error);
} }
} else { } else {
Locator.getInstance().getNotifier().showMessage(R.string.not_valid_result, MessageType.error); getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
} }
} }
public static void createFunction(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) { public static void tryCreateFunction(@NotNull final Context context) {
final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState(); final CalculatorDisplay display = Locator.getInstance().getDisplay();
final CalculatorDisplayViewState viewState = display.getViewState();
if (viewState.isValid() ) { if (viewState.isValid() ) {
final String functionValue = viewState.getText(); final String functionValue = viewState.getText();
@ -137,10 +141,37 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
FunctionEditDialogFragment.showDialog(FunctionEditDialogFragment.Input.newFromDisplay(viewState), context); FunctionEditDialogFragment.showDialog(FunctionEditDialogFragment.Input.newFromDisplay(viewState), context);
} else { } else {
Locator.getInstance().getNotifier().showMessage(R.string.empty_function_error, MessageType.error); getNotifier().showMessage(R.string.empty_function_error, MessageType.error);
} }
} else { } else {
Locator.getInstance().getNotifier().showMessage(R.string.not_valid_result, MessageType.error); getNotifier().showMessage(R.string.not_valid_result, MessageType.error);
}
}
@NotNull
private static CalculatorNotifier getNotifier() {
return Locator.getInstance().getNotifier();
}
public static void tryPlot() {
final CalculatorPlotter plotter = Locator.getInstance().getPlotter();
final CalculatorDisplay display = Locator.getInstance().getDisplay();
final CalculatorDisplayViewState viewState = display.getViewState();
if (viewState.isValid() ) {
final String functionValue = viewState.getText();
final Generic expression = viewState.getResult();
if (!StringUtils.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);
} }
} }
@ -190,7 +221,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
App.getInstance().getUiThreadExecutor().execute(new Runnable() { App.getInstance().getUiThreadExecutor().execute(new Runnable() {
@Override @Override
public void run() { public void run() {
CalculatorActivityLauncher.createVar(context, Locator.getInstance().getDisplay()); CalculatorActivityLauncher.tryCreateVar(context);
} }
}); });
break; break;
@ -198,7 +229,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener
App.getInstance().getUiThreadExecutor().execute(new Runnable() { App.getInstance().getUiThreadExecutor().execute(new Runnable() {
@Override @Override
public void run() { public void run() {
CalculatorActivityLauncher.createFunction(context, Locator.getInstance().getDisplay()); CalculatorActivityLauncher.tryCreateFunction(context);
} }
}); });
break; break;

View File

@ -8,10 +8,10 @@ package org.solovyev.android.calculator;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.drag.DragDirection;
import org.solovyev.android.view.drag.SimpleOnDragListener;
import org.solovyev.android.view.drag.DirectionDragButton; import org.solovyev.android.view.drag.DirectionDragButton;
import org.solovyev.android.view.drag.DragButton; import org.solovyev.android.view.drag.DragButton;
import org.solovyev.android.view.drag.DragDirection;
import org.solovyev.android.view.drag.SimpleOnDragListener;
import org.solovyev.common.math.Point2d; import org.solovyev.common.math.Point2d;
/** /**
@ -19,9 +19,9 @@ import org.solovyev.common.math.Point2d;
* Date: 10/24/11 * Date: 10/24/11
* Time: 9:52 PM * Time: 9:52 PM
*/ */
public class EvalDragProcessor implements SimpleOnDragListener.DragProcessor { public class EqualsDragProcessor implements SimpleOnDragListener.DragProcessor {
public EvalDragProcessor() { public EqualsDragProcessor() {
} }
@Override @Override
@ -29,12 +29,17 @@ public class EvalDragProcessor implements SimpleOnDragListener.DragProcessor {
boolean result = false; boolean result = false;
if (dragButton instanceof DirectionDragButton) { if (dragButton instanceof DirectionDragButton) {
String text = ((DirectionDragButton) dragButton).getText(dragDirection); if (dragDirection == DragDirection.down) {
if ("".equals(text)) { CalculatorActivityLauncher.tryPlot();
Locator.getInstance().getCalculator().simplify(); result = true;
result = true; } else {
} final String text = ((DirectionDragButton) dragButton).getText(dragDirection);
} if ("".equals(text)) {
Locator.getInstance().getCalculator().simplify();
result = true;
}
}
}
return result; return result;
} }

View File

@ -65,11 +65,20 @@ public class CalculatorPlotterImpl implements CalculatorPlotter {
yVariable = null; yVariable = null;
} }
final PlotFunction realPlotFunction = newPlotFunction(new XyFunction(expression, xVariable, yVariable, false)); final XyFunction realXyFunction = new XyFunction(expression, xVariable, yVariable, false);
final PlotFunction imagPlotFunction = newPlotFunction(new XyFunction(expression, xVariable, yVariable, true)); 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); removeAllUnpinnedExcept(realPlotFunction, imagPlotFunction);
// create plot functions with freed line definitions
realPlotFunction = newPlotFunction(realXyFunction);
imagPlotFunction = newPlotFunction(imagXyFunction);
final boolean realAdded = addFunction(realPlotFunction); final boolean realAdded = addFunction(realPlotFunction);
final boolean imagAdded = addFunction(plotImag ? imagPlotFunction : PlotFunction.invisible(imagPlotFunction)); final boolean imagAdded = addFunction(plotImag ? imagPlotFunction : PlotFunction.invisible(imagPlotFunction));
@ -95,7 +104,6 @@ public class CalculatorPlotterImpl implements CalculatorPlotter {
} }
} }
private boolean removeAllUnpinnedExcept(@NotNull final PlotFunction... exceptFunctions) { private boolean removeAllUnpinnedExcept(@NotNull final PlotFunction... exceptFunctions) {
synchronized (functions) { synchronized (functions) {

View File

@ -12,16 +12,16 @@ public enum PlotLineColor {
// Color.WHITE // Color.WHITE
white(0xFFFFFFFF), white(0xFFFFFFFF),
// Color.GRAY blue(0xFF10648C),
grey(0xFF888888),
// Color.RED // Color.RED
red(0xFFFF0000), red(0xFFFF0000),
blue(0xFF10648C),
// Color.GREEN // Color.GREEN
green(0xFF00FF00); green(0xFF00FF00),
// Color.GRAY
grey(0xFF888888);
private final int color; private final int color;