new plotter
This commit is contained in:
parent
8fb1272bd2
commit
f08e03761b
BIN
android-app-core/res/drawable-hdpi/ab_camera.png
Normal file
BIN
android-app-core/res/drawable-hdpi/ab_camera.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
android-app-core/res/drawable-ldpi/ab_camera.png
Normal file
BIN
android-app-core/res/drawable-ldpi/ab_camera.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
android-app-core/res/drawable-mdpi/ab_camera.png
Normal file
BIN
android-app-core/res/drawable-mdpi/ab_camera.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 981 B |
BIN
android-app-core/res/drawable-xhdpi/ab_camera.png
Normal file
BIN
android-app-core/res/drawable-xhdpi/ab_camera.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -298,6 +298,8 @@
|
||||
<string name="cpp_dash_dotted_line_style">Dash dotted (-.-.-)</string>
|
||||
|
||||
<string name="cpp_plotter">Function plotter</string>
|
||||
|
||||
<string name="cpp_plot_screenshot">Capture screenshot</string>
|
||||
<string name="cpp_plot_screenshot_saved">Screenshot successfully saved: %1$s!</string>
|
||||
<string name="cpp_plot_unable_to_save_screenshot">Screenshot cannot be saved as sdcard is not mounted. Mount sdcard and try again!</string>
|
||||
|
||||
</resources>
|
@ -6,7 +6,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -67,14 +66,10 @@ public final class AndroidUtils2 {
|
||||
public static String saveBitmap(@NotNull Bitmap bitmap,
|
||||
@NotNull String path,
|
||||
@NotNull String fileName) {
|
||||
final File sdcardPath = Environment.getExternalStorageDirectory();
|
||||
final File filePath = new File(sdcardPath, path);
|
||||
|
||||
final File filePath = new File(path);
|
||||
filePath.mkdirs();
|
||||
|
||||
final String fullFileName = fileName + "_" + System.currentTimeMillis() + ".png";
|
||||
|
||||
final File file = new File(path, fullFileName);
|
||||
final File file = new File(path, fileName);
|
||||
if (!file.exists()) {
|
||||
final String name = file.getAbsolutePath();
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="com.android.vending.BILLING"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<!--TODO: REMOVE IN PRODUCTION-->
|
||||
<!--<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>-->
|
||||
|
@ -23,6 +23,11 @@
|
||||
a:icon="@drawable/ab_list"
|
||||
a:showAsAction="always"/>
|
||||
|
||||
<item a:id="@+id/menu_plot_schreeshot"
|
||||
a:title="@string/cpp_plot_screenshot"
|
||||
a:icon="@drawable/ab_camera"
|
||||
a:showAsAction="always"/>
|
||||
|
||||
<item a:id="@+id/menu_plot_settings"
|
||||
a:title="@string/c_settings"
|
||||
a:icon="@drawable/ab_settings"
|
||||
|
@ -2,8 +2,10 @@ package org.solovyev.android.calculator.plot;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.view.View;
|
||||
@ -13,17 +15,30 @@ import com.actionbarsherlock.view.MenuItem;
|
||||
import org.achartengine.renderer.XYMultipleSeriesRenderer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.*;
|
||||
import org.solovyev.android.AndroidUtils2;
|
||||
import org.solovyev.android.calculator.CalculatorApplication;
|
||||
import org.solovyev.android.calculator.CalculatorEventData;
|
||||
import org.solovyev.android.calculator.CalculatorEventHolder;
|
||||
import org.solovyev.android.calculator.CalculatorEventListener;
|
||||
import org.solovyev.android.calculator.CalculatorEventType;
|
||||
import org.solovyev.android.calculator.CalculatorFragment;
|
||||
import org.solovyev.android.calculator.CalculatorUtils;
|
||||
import org.solovyev.android.calculator.Locator;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.menu.AMenuItem;
|
||||
import org.solovyev.android.menu.ActivityMenu;
|
||||
import org.solovyev.android.menu.IdentifiableMenuItem;
|
||||
import org.solovyev.android.menu.ListActivityMenu;
|
||||
import org.solovyev.android.sherlock.menu.SherlockMenuHelper;
|
||||
import org.solovyev.common.JPredicate;
|
||||
import org.solovyev.common.msg.MessageType;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -68,6 +83,10 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
@NotNull
|
||||
private PlotData plotData = new PlotData(Collections.<PlotFunction>emptyList(), false);
|
||||
|
||||
@NotNull
|
||||
private PlotBoundaries initialPlotBoundaries;
|
||||
|
||||
|
||||
@NotNull
|
||||
private ActivityMenu<Menu, MenuItem> fragmentMenu;
|
||||
|
||||
@ -85,8 +104,8 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
public void onCreate(Bundle in) {
|
||||
super.onCreate(in);
|
||||
|
||||
// todo serso: init variable properly
|
||||
boolean paneFragment = true;
|
||||
@ -96,6 +115,19 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
this.bgColor = getResources().getColor(android.R.color.transparent);
|
||||
}
|
||||
|
||||
final PlotBoundaries savedPlotBoundaries;
|
||||
if (in != null) {
|
||||
savedPlotBoundaries = (PlotBoundaries) in.getSerializable(PLOT_BOUNDARIES);
|
||||
} else {
|
||||
savedPlotBoundaries = null;
|
||||
}
|
||||
|
||||
if (savedPlotBoundaries != null) {
|
||||
initialPlotBoundaries = savedPlotBoundaries;
|
||||
} else {
|
||||
initialPlotBoundaries = PlotBoundaries.newDefaultInstance();
|
||||
}
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -117,8 +149,8 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
super.onResume();
|
||||
|
||||
plotData = Locator.getInstance().getPlotter().getPlotData();
|
||||
createChart(plotData);
|
||||
createGraphicalView(getView(), plotData);
|
||||
createChart(plotData, initialPlotBoundaries);
|
||||
createGraphicalView(getView(), plotData, initialPlotBoundaries);
|
||||
getSherlockActivity().invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@ -140,11 +172,11 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
public void run() {
|
||||
getSherlockActivity().invalidateOptionsMenu();
|
||||
|
||||
createChart(plotData);
|
||||
createChart(plotData, initialPlotBoundaries);
|
||||
|
||||
final View view = getView();
|
||||
if (view != null) {
|
||||
createGraphicalView(view, plotData);
|
||||
createGraphicalView(view, plotData, initialPlotBoundaries);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -152,16 +184,16 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
|
||||
protected abstract void onError();
|
||||
|
||||
protected abstract void createGraphicalView(@NotNull View view, @NotNull PlotData plotData);
|
||||
protected abstract void createGraphicalView(@NotNull View view, @NotNull PlotData plotData, @NotNull PlotBoundaries plotBoundaries);
|
||||
|
||||
protected abstract void createChart(@NotNull PlotData plotData);
|
||||
protected abstract void createChart(@NotNull PlotData plotData, @NotNull PlotBoundaries plotBoundaries);
|
||||
|
||||
|
||||
protected double getMaxValue(@Nullable PlotBoundaries plotBoundaries) {
|
||||
protected double getMaxXValue(@Nullable PlotBoundaries plotBoundaries) {
|
||||
return plotBoundaries == null ? DEFAULT_MAX_NUMBER : plotBoundaries.getXMax();
|
||||
}
|
||||
|
||||
protected double getMinValue(@Nullable PlotBoundaries plotBoundaries) {
|
||||
protected double getMinXValue(@Nullable PlotBoundaries plotBoundaries) {
|
||||
return plotBoundaries == null ? DEFAULT_MIN_NUMBER : plotBoundaries.getXMin();
|
||||
}
|
||||
|
||||
@ -232,8 +264,23 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
};
|
||||
menuItems.add(plot2dMenuItem);
|
||||
|
||||
final IdentifiableMenuItem<MenuItem> captureScreenshotMenuItem = new IdentifiableMenuItem<MenuItem>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Integer getItemId() {
|
||||
return R.id.menu_plot_schreeshot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NotNull MenuItem data, @NotNull Context context) {
|
||||
captureScreehshot();
|
||||
}
|
||||
};
|
||||
menuItems.add(captureScreenshotMenuItem);
|
||||
|
||||
final boolean plot3dVisible = !plotData.isPlot3d() && is3dPlotSupported();
|
||||
final boolean plot2dVisible = plotData.isPlot3d() && Locator.getInstance().getPlotter().is2dPlotPossible();
|
||||
final boolean captureScreenshotVisible = isScreenshotSupported();
|
||||
fragmentMenu = ListActivityMenu.fromResource(R.menu.plot_menu, menuItems, SherlockMenuHelper.getInstance(), new JPredicate<AMenuItem<MenuItem>>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable AMenuItem<MenuItem> menuItem) {
|
||||
@ -241,6 +288,8 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
return !plot3dVisible;
|
||||
} else if ( menuItem == plot2dMenuItem ) {
|
||||
return !plot2dVisible;
|
||||
} else if ( menuItem == captureScreenshotMenuItem ) {
|
||||
return !captureScreenshotVisible;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -252,6 +301,33 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isScreenshotSupported();
|
||||
|
||||
@NotNull
|
||||
protected abstract Bitmap getScreehshot();
|
||||
|
||||
private void captureScreehshot() {
|
||||
if ( isScreenshotSupported() ) {
|
||||
final Bitmap screenshot = getScreehshot();
|
||||
final String screenShotFileName = generateScreenshotFileName();
|
||||
final File externalFilesDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
|
||||
if (externalFilesDir != null) {
|
||||
final String path = externalFilesDir.getPath();
|
||||
AndroidUtils2.saveBitmap(screenshot, path, screenShotFileName);
|
||||
Locator.getInstance().getNotifier().showMessage(R.string.cpp_plot_screenshot_saved, MessageType.info, path + "/" + screenShotFileName);
|
||||
} else {
|
||||
Locator.getInstance().getNotifier().showMessage(R.string.cpp_plot_unable_to_save_screenshot, MessageType.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String generateScreenshotFileName() {
|
||||
final Date now = new Date();
|
||||
final String timestamp = new SimpleDateFormat("yyyy.MM.dd HH.mm.ss.S").format(now);
|
||||
|
||||
return "cpp-screenshot-" + timestamp + ".png";
|
||||
}
|
||||
|
||||
protected abstract boolean is3dPlotSupported();
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -35,7 +36,7 @@ public class CalculatorArityPlotFragment extends AbstractCalculatorPlotFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createGraphicalView(@NotNull View root, @NotNull PlotData plotData) {
|
||||
protected void createGraphicalView(@NotNull View root, @NotNull PlotData plotData, @NotNull PlotBoundaries plotBoundaries) {
|
||||
|
||||
// remove old
|
||||
final ViewGroup graphContainer = (ViewGroup) root.findViewById(R.id.main_fragment_layout);
|
||||
@ -74,12 +75,25 @@ public class CalculatorArityPlotFragment extends AbstractCalculatorPlotFragment
|
||||
|
||||
graphView.init(FunctionViewDef.newInstance(Color.WHITE, Color.WHITE, Color.DKGRAY, getBgColor()));
|
||||
graphView.setFunctionPlotDefs(arityFunctions);
|
||||
graphView.setXRange((float)plotBoundaries.getXMin(), (float)plotBoundaries.getXMax());
|
||||
|
||||
graphContainer.addView((View) graphView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createChart(@NotNull PlotData plotData) {
|
||||
protected void createChart(@NotNull PlotData plotData, @NotNull PlotBoundaries plotBoundaries) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isScreenshotSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Bitmap getScreehshot() {
|
||||
assert this.graphView != null;
|
||||
return this.graphView.captureScreenshot();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -11,9 +11,13 @@ import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.AndroidUtils2;
|
||||
|
||||
import javax.microedition.khronos.egl.*;
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGL11;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
import javax.microedition.khronos.egl.EGLSurface;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.microedition.khronos.opengles.GL11;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -36,10 +40,11 @@ abstract class GLView extends SurfaceView implements SurfaceHolder.Callback {
|
||||
|
||||
abstract void onSurfaceCreated(GL10 gl, int width, int height);
|
||||
|
||||
public String captureScreenshot() {
|
||||
Bitmap bitmap = getRawPixels(gl, width, height);
|
||||
bitmapBGRtoRGB(bitmap, width, height);
|
||||
return AndroidUtils2.saveBitmap(bitmap, GraphView.SCREENSHOT_DIR, "calculator");
|
||||
@NotNull
|
||||
public Bitmap captureScreenshot() {
|
||||
final Bitmap result = getRawPixels(gl, width, height);
|
||||
bitmapBGRtoRGB(result, width, height);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Bitmap getRawPixels(GL10 gl, int width, int height) {
|
||||
|
@ -4,7 +4,12 @@ package org.solovyev.android.calculator.plot;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -12,7 +17,6 @@ import android.widget.Scroller;
|
||||
import android.widget.ZoomButtonsController;
|
||||
import org.javia.arity.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.AndroidUtils2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -67,11 +71,19 @@ public class Graph2dView extends View implements GraphView {
|
||||
textPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
public String captureScreenshot() {
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
@NotNull
|
||||
public Bitmap captureScreenshot() {
|
||||
final Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(result);
|
||||
onDraw(canvas);
|
||||
return AndroidUtils2.saveBitmap(bitmap, GraphView.SCREENSHOT_DIR, "calculator");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXRange(float xMin, float xMax) {
|
||||
this.gwidth = xMax - xMin;
|
||||
this.currentX = xMax - this.gwidth / 2;
|
||||
|
||||
}
|
||||
|
||||
private void clearAllGraphs() {
|
||||
@ -517,11 +529,11 @@ public class Graph2dView extends View implements GraphView {
|
||||
}
|
||||
|
||||
private boolean canZoomIn() {
|
||||
return gwidth > 1f;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canZoomOut() {
|
||||
return gwidth < 50;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void invalidateGraphs() {
|
||||
|
@ -4,7 +4,12 @@ package org.solovyev.android.calculator.plot;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -12,7 +17,6 @@ import android.widget.Scroller;
|
||||
import android.widget.ZoomButtonsController;
|
||||
import org.javia.arity.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.AndroidUtils2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -94,11 +98,18 @@ public class Graph2dViewNew extends View implements GraphView {
|
||||
height = this.getHeight();
|
||||
}
|
||||
|
||||
public String captureScreenshot() {
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
@NotNull
|
||||
public Bitmap captureScreenshot() {
|
||||
final Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(result);
|
||||
onDraw(canvas);
|
||||
return AndroidUtils2.saveBitmap(bitmap, GraphView.SCREENSHOT_DIR, "calculator");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXRange(float xMin, float xMax) {
|
||||
this.x0 = xMin + graphWidth / 2;
|
||||
this.graphWidth = xMax - xMin;
|
||||
}
|
||||
|
||||
private void clearAllGraphs() {
|
||||
|
@ -101,11 +101,11 @@ public class Graph3dView extends GLView implements GraphView {
|
||||
}
|
||||
|
||||
private boolean canZoomIn(float zoom) {
|
||||
return zoom > .2f;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canZoomOut(float zoom) {
|
||||
return zoom < 5;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -190,6 +190,11 @@ public class Graph3dView extends GLView implements GraphView {
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXRange(float xMin, float xMax) {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated(GL10 gl, int width, int height) {
|
||||
gl.glDisable(GL10.GL_DITHER);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.widget.ZoomButtonsController;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -18,7 +19,13 @@ public interface GraphView extends ZoomButtonsController.OnZoomListener, TouchHa
|
||||
public void onPause();
|
||||
public void onResume();
|
||||
|
||||
public String captureScreenshot();
|
||||
@NotNull
|
||||
public Bitmap captureScreenshot();
|
||||
|
||||
void setXRange(float xMin, float xMax);
|
||||
|
||||
/* void increaseDensity();
|
||||
void decreaseDensity();*/
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user