diff --git a/android-app-core/res/values/text_strings.xml b/android-app-core/res/values/text_strings.xml index 33c02872..aa256f10 100644 --- a/android-app-core/res/values/text_strings.xml +++ b/android-app-core/res/values/text_strings.xml @@ -310,6 +310,9 @@ Function Pinned Visible + +plot + Unable to plot empty function! + Unable to plot: too many variables! \ No newline at end of file diff --git a/android-app/res/layout/cpp_drag_button_equals.xml b/android-app/res/layout/cpp_drag_button_equals.xml index e000acf0..80aa5baf 100644 --- a/android-app/res/layout/cpp_drag_button_equals.xml +++ b/android-app/res/layout/cpp_drag_button_equals.xml @@ -11,6 +11,7 @@ a:id="@id/cpp_button_equals" c:textUp="≡" a:text="=" + c:textDown="@string/cpp_plot_button_text" c:directionTextScale="0.5" a:layout_width="fill_parent" a:layout_height="fill_parent" diff --git a/android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java b/android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java index 0ba59f44..b6bd2a20 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/AbstractCalculatorHelper.java @@ -120,7 +120,7 @@ public abstract class AbstractCalculatorHelper implements SharedPreferences.OnSh final DragButton equalsButton = getButton(root, R.id.cpp_button_equals); 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); diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java index 6c4d6367..a368efa1 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorActivityLauncher.java @@ -11,6 +11,7 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; import com.actionbarsherlock.app.SherlockFragmentActivity; +import jscl.math.Generic; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; 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.matrix.CalculatorMatrixActivity; 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.MessageType; import org.solovyev.common.text.StringUtils; @@ -102,8 +104,9 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener context.startActivity(intent); } - public static void createVar(@NotNull final Context context, @NotNull CalculatorDisplay calculatorDisplay) { - final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState(); + public static void tryCreateVar(@NotNull final Context context) { + final CalculatorDisplay display = Locator.getInstance().getDisplay(); + final CalculatorDisplayViewState viewState = display.getViewState(); if (viewState.isValid() ) { final String varValue = viewState.getText(); if (!StringUtils.isEmpty(varValue)) { @@ -117,18 +120,19 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener context.startActivity(intent); } } 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 { - Locator.getInstance().getNotifier().showMessage(R.string.empty_var_error, MessageType.error); + getNotifier().showMessage(R.string.empty_var_error, MessageType.error); } } 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) { - final CalculatorDisplayViewState viewState = calculatorDisplay.getViewState(); + public static void tryCreateFunction(@NotNull final Context context) { + final CalculatorDisplay display = Locator.getInstance().getDisplay(); + final CalculatorDisplayViewState viewState = display.getViewState(); if (viewState.isValid() ) { final String functionValue = viewState.getText(); @@ -137,10 +141,37 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener FunctionEditDialogFragment.showDialog(FunctionEditDialogFragment.Input.newFromDisplay(viewState), context); } else { - Locator.getInstance().getNotifier().showMessage(R.string.empty_function_error, MessageType.error); + getNotifier().showMessage(R.string.empty_function_error, MessageType.error); } } 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() { @Override public void run() { - CalculatorActivityLauncher.createVar(context, Locator.getInstance().getDisplay()); + CalculatorActivityLauncher.tryCreateVar(context); } }); break; @@ -198,7 +229,7 @@ public final class CalculatorActivityLauncher implements CalculatorEventListener App.getInstance().getUiThreadExecutor().execute(new Runnable() { @Override public void run() { - CalculatorActivityLauncher.createFunction(context, Locator.getInstance().getDisplay()); + CalculatorActivityLauncher.tryCreateFunction(context); } }); break; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java b/android-app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java similarity index 61% rename from android-app/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java rename to android-app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java index 4447adf1..e6d38f23 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/EvalDragProcessor.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/EqualsDragProcessor.java @@ -8,10 +8,10 @@ package org.solovyev.android.calculator; import android.view.MotionEvent; 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.DragButton; +import org.solovyev.android.view.drag.DragDirection; +import org.solovyev.android.view.drag.SimpleOnDragListener; import org.solovyev.common.math.Point2d; /** @@ -19,9 +19,9 @@ import org.solovyev.common.math.Point2d; * Date: 10/24/11 * Time: 9:52 PM */ -public class EvalDragProcessor implements SimpleOnDragListener.DragProcessor { +public class EqualsDragProcessor implements SimpleOnDragListener.DragProcessor { - public EvalDragProcessor() { + public EqualsDragProcessor() { } @Override @@ -29,12 +29,17 @@ public class EvalDragProcessor implements SimpleOnDragListener.DragProcessor { boolean result = false; if (dragButton instanceof DirectionDragButton) { - String text = ((DirectionDragButton) dragButton).getText(dragDirection); - if ("≡".equals(text)) { - Locator.getInstance().getCalculator().simplify(); - result = true; - } - } + if (dragDirection == DragDirection.down) { + CalculatorActivityLauncher.tryPlot(); + result = true; + } else { + final String text = ((DirectionDragButton) dragButton).getText(dragDirection); + if ("≡".equals(text)) { + Locator.getInstance().getCalculator().simplify(); + result = true; + } + } + } return result; } diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java b/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java index 10ca012e..4f27c88d 100644 --- a/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java +++ b/core/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotterImpl.java @@ -65,11 +65,20 @@ public class CalculatorPlotterImpl implements CalculatorPlotter { yVariable = null; } - final PlotFunction realPlotFunction = newPlotFunction(new XyFunction(expression, xVariable, yVariable, false)); - final PlotFunction imagPlotFunction = newPlotFunction(new XyFunction(expression, xVariable, yVariable, true)); + 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)); @@ -95,7 +104,6 @@ public class CalculatorPlotterImpl implements CalculatorPlotter { } } - private boolean removeAllUnpinnedExcept(@NotNull final PlotFunction... exceptFunctions) { synchronized (functions) { diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/PlotLineColor.java b/core/src/main/java/org/solovyev/android/calculator/plot/PlotLineColor.java index 8b9e614c..f767ac69 100644 --- a/core/src/main/java/org/solovyev/android/calculator/plot/PlotLineColor.java +++ b/core/src/main/java/org/solovyev/android/calculator/plot/PlotLineColor.java @@ -12,16 +12,16 @@ public enum PlotLineColor { // Color.WHITE white(0xFFFFFFFF), - // Color.GRAY - grey(0xFF888888), + blue(0xFF10648C), // Color.RED red(0xFFFF0000), - blue(0xFF10648C), - // Color.GREEN - green(0xFF00FF00); + green(0xFF00FF00), + + // Color.GRAY + grey(0xFF888888); private final int color;