new plotter

This commit is contained in:
Sergey Solovyev
2013-01-14 17:52:22 +04:00
parent 8fb1272bd2
commit f08e03761b
15 changed files with 187 additions and 54 deletions

View File

@@ -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,7 +83,11 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
@NotNull
private PlotData plotData = new PlotData(Collections.<PlotFunction>emptyList(), false);
@NotNull
@NotNull
private PlotBoundaries initialPlotBoundaries;
@NotNull
private ActivityMenu<Menu, MenuItem> fragmentMenu;
// thread which calculated data for graph view
@@ -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,7 +115,20 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
this.bgColor = getResources().getColor(android.R.color.transparent);
}
setHasOptionsMenu(true);
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);
}
@Override
@@ -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();
}
@@ -227,13 +259,28 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
@Override
public void onClick(@NotNull MenuItem data, @NotNull Context context) {
Locator.getInstance().getPlotter().setPlot3d(false);
Locator.getInstance().getPlotter().setPlot3d(false);
}
};
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,7 +288,9 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
return !plot3dVisible;
} else if ( menuItem == plot2dMenuItem ) {
return !plot2dVisible;
}
} else if ( menuItem == captureScreenshotMenuItem ) {
return !captureScreenshotVisible;
}
return false;
}
});
@@ -252,7 +301,34 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
}
}
protected abstract boolean is3dPlotSupported();
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
public void onPrepareOptionsMenu(Menu menu) {

View File

@@ -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,15 +75,28 @@ 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
@Override
protected boolean isScreenshotSupported() {
return true;
}
@NotNull
@Override
protected Bitmap getScreehshot() {
assert this.graphView != null;
return this.graphView.captureScreenshot();
}
@Override
protected boolean is3dPlotSupported() {
return true;
}

View File

@@ -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) {

View File

@@ -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,14 +71,22 @@ 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;
}
private void clearAllGraphs() {
@Override
public void setXRange(float xMin, float xMax) {
this.gwidth = xMax - xMin;
this.currentX = xMax - this.gwidth / 2;
}
private void clearAllGraphs() {
for (GraphData graph : graphs) {
graph.clear();
}
@@ -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() {

View File

@@ -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,14 +98,21 @@ 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;
}
private void clearAllGraphs() {
@Override
public void setXRange(float xMin, float xMax) {
this.x0 = xMin + graphWidth / 2;
this.graphWidth = xMax - xMin;
}
private void clearAllGraphs() {
for (GraphData graph : graphs) {
graph.clear();
}

View File

@@ -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,7 +190,12 @@ public class Graph3dView extends GLView implements GraphView {
isDirty = true;
}
@Override
@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);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

View File

@@ -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();*/
/*
**********************************************************************