diff --git a/android-app-tests/android-app-tests.iml b/android-app-tests/android-app-tests.iml index 35cfdfec..208f6f2c 100644 --- a/android-app-tests/android-app-tests.iml +++ b/android-app-tests/android-app-tests.iml @@ -75,6 +75,7 @@ + @@ -91,20 +92,21 @@ - + - + - + + diff --git a/android-app/android-app.iml b/android-app/android-app.iml index bc2e2ca8..72853a65 100644 --- a/android-app/android-app.iml +++ b/android-app/android-app.iml @@ -87,6 +87,7 @@ + @@ -134,6 +135,7 @@ + diff --git a/android-app/build.gradle b/android-app/build.gradle index 59303454..c425b221 100644 --- a/android-app/build.gradle +++ b/android-app/build.gradle @@ -50,6 +50,12 @@ android { } } +repositories { + flatDir{ + dirs 'misc/libs' + } +} + dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':core') @@ -76,6 +82,7 @@ dependencies { compile 'com.google.android.gms:play-services-base:7.5.0@aar' compile 'com.google.android.gms:play-services-analytics:7.5.0@aar' compile 'com.melnykov:floatingactionbutton:1.1.0' + compile(name:'plotter', ext:'aar') debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' diff --git a/android-app/src/main/java/org/solovyev/android/calculator/App.java b/android-app/src/main/java/org/solovyev/android/calculator/App.java index 0fefb55d..db562b17 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/App.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/App.java @@ -55,6 +55,8 @@ import org.solovyev.android.checkout.ProductTypes; import org.solovyev.android.checkout.Products; import org.solovyev.android.checkout.RobotmediaDatabase; import org.solovyev.android.checkout.RobotmediaInventory; +import org.solovyev.android.plotter.Plot; +import org.solovyev.android.plotter.Plotter; import org.solovyev.common.listeners.JEvent; import org.solovyev.common.listeners.JEventListener; import org.solovyev.common.listeners.JEventListeners; @@ -120,6 +122,9 @@ public final class App { @Nonnull private static volatile ScreenMetrics screenMetrics; + @Nonnull + private static volatile Plotter plotter; + @Nonnull private static final Languages languages = new Languages(); @@ -184,6 +189,7 @@ public final class App { } } App.languages.init(App.preferences); + App.plotter = Plot.newPlotter(application); App.initialized = true; } else { @@ -342,4 +348,9 @@ public final class App { // Create and show the dialog. dialogFragment.show(ft, fragmentTag); } + + @Nonnull + public static Plotter getPlotter() { + return plotter; + } } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorFragmentType.java b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorFragmentType.java index ae3ed931..22b0538e 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/CalculatorFragmentType.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/CalculatorFragmentType.java @@ -23,6 +23,7 @@ package org.solovyev.android.calculator; import android.support.v4.app.Fragment; + import org.solovyev.android.calculator.about.CalculatorAboutFragment; import org.solovyev.android.calculator.about.CalculatorReleaseNotesFragment; import org.solovyev.android.calculator.history.HistoryFragment; @@ -31,10 +32,10 @@ import org.solovyev.android.calculator.math.edit.CalculatorFunctionsFragment; import org.solovyev.android.calculator.math.edit.CalculatorOperatorsFragment; import org.solovyev.android.calculator.math.edit.CalculatorVarsFragment; import org.solovyev.android.calculator.matrix.CalculatorMatrixEditFragment; -import org.solovyev.android.calculator.plot.CalculatorPlotFragment; import org.solovyev.android.calculator.plot.CalculatorPlotFunctionSettingsActivity; import org.solovyev.android.calculator.plot.CalculatorPlotFunctionsActivity; import org.solovyev.android.calculator.plot.CalculatorPlotRangeActivity; +import org.solovyev.android.calculator.plot.PlotterFragment; import javax.annotation.Nonnull; @@ -53,7 +54,7 @@ public enum CalculatorFragmentType { variables(CalculatorVarsFragment.class, R.layout.vars_fragment, R.string.c_vars), functions(CalculatorFunctionsFragment.class, R.layout.math_entities_fragment, R.string.c_functions), operators(CalculatorOperatorsFragment.class, R.layout.math_entities_fragment, R.string.c_operators), - plotter(CalculatorPlotFragment.class, R.layout.cpp_plot_fragment, R.string.c_graph), + plotter(PlotterFragment.class, R.layout.cpp_plotter_fragment, R.string.c_graph), plotter_functions(CalculatorPlotFunctionsActivity.CalculatorPlotFunctionsFragment.class, R.layout.cpp_plot_functions_fragment, R.string.cpp_plot_functions), plotter_function_settings(CalculatorPlotFunctionSettingsActivity.CalculatorPlotFunctionSettingsFragment.class, R.layout.cpp_plot_function_settings_fragment, R.string.cpp_plot_function_settings), plotter_range(CalculatorPlotRangeActivity.CalculatorPlotRangeFragment.class, R.layout.cpp_plot_range_fragment, R.string.cpp_plot_range), diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/PlotterFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/PlotterFragment.java new file mode 100644 index 00000000..51359012 --- /dev/null +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/PlotterFragment.java @@ -0,0 +1,141 @@ +package org.solovyev.android.calculator.plot; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcelable; +import android.support.annotation.ColorInt; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import org.solovyev.android.calculator.App; +import org.solovyev.android.calculator.CalculatorFragment; +import org.solovyev.android.calculator.CalculatorFragmentType; +import org.solovyev.android.calculator.R; +import org.solovyev.android.calculator.preferences.PreferencesActivity; +import org.solovyev.android.plotter.PlotView; +import org.solovyev.android.plotter.Plotter; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class PlotterFragment extends CalculatorFragment { + + @Nonnull + private final Plotter plotter = App.getPlotter(); + + private PlotView plotView; + + public PlotterFragment() { + super(CalculatorFragmentType.plotter); + } + + @Override + public void onCreate(@Nullable Bundle in) { + super.onCreate(in); + setHasOptionsMenu(true); + } + + @ColorInt + private int getBgColor() { + if (isPaneFragment()) { + return getBgColor(R.color.cpp_pane_bg_light, R.color.cpp_pane_bg); + } else { + return getBgColor(R.color.cpp_main_bg_light, R.color.cpp_main_bg); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View view = super.onCreateView(inflater, container, savedInstanceState); + plotView = (PlotView) view.findViewById(R.id.plotview); + plotView.setPlotter(plotter); + plotView.setBackgroundColor(getBgColor()); + + if (savedInstanceState != null) { + final Parcelable plotviewState = savedInstanceState.getParcelable("plotview"); + if (plotviewState != null) { + plotView.onRestoreInstanceState(plotviewState); + } + } + + final View zoomOutButton = view.findViewById(R.id.zoom_out_button); + zoomOutButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + plotView.zoom(false); + } + }); + final View zoom0Button = view.findViewById(R.id.zoom_0_button); + zoom0Button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + plotView.resetCamera(); + plotView.resetZoom(); + } + }); + final View zoomInButton = view.findViewById(R.id.zoom_in_button); + zoomInButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + plotView.zoom(true); + } + }); + final View plotModeButton = view.findViewById(R.id.plot_mode_button); + plotModeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + plotter.set3d(!plotter.is3d()); + } + }); + + return view; + } + + @ColorInt + @SuppressWarnings("deprecation") + private int getBgColor(int lightColor, int darkColor) { + return getResources().getColor(App.getTheme().isLight() ? lightColor : darkColor); + } + + @Override + public void onSaveInstanceState(@Nonnull Bundle out) { + super.onSaveInstanceState(out); + final Parcelable plotViewState = plotView.onSaveInstanceState(); + out.putParcelable("plotview", plotViewState); + } + + @Override + public void onPause() { + plotView.onPause(); + super.onPause(); + } + + @Override + public void onResume() { + super.onResume(); + plotView.onResume(); + } + + @Override + public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.plot_menu, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_plot_functions: + startActivity(new Intent(getActivity(), CalculatorPlotFunctionsActivity.class)); + return true; + case R.id.menu_plot_settings: + PreferencesActivity.start(getActivity(), R.xml.preferences_plot, R.string.prefs_graph_screen_title); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/android-app/src/main/res/layout/cpp_plotter_fragment.xml b/android-app/src/main/res/layout/cpp_plotter_fragment.xml new file mode 100644 index 00000000..7f3fa915 --- /dev/null +++ b/android-app/src/main/res/layout/cpp_plotter_fragment.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + +