WarpPI/src/org/warp/picalculator/gui/screens/MathInputScreen.java

771 lines
24 KiB
Java
Raw Normal View History

package org.warp.picalculator.gui.screens;
2016-09-02 20:32:37 +02:00
import java.io.PrintWriter;
import java.io.StringWriter;
2016-10-02 16:01:41 +02:00
import java.util.ArrayList;
2017-01-16 17:57:09 +01:00
import java.util.Collections;
import java.util.Iterator;
2017-01-16 17:57:09 +01:00
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
2016-09-02 20:32:37 +02:00
import org.warp.picalculator.Error;
import org.warp.picalculator.Errors;
import org.warp.picalculator.Main;
2016-09-02 20:32:37 +02:00
import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.Renderer;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.AngleMode;
import org.warp.picalculator.math.Calculator;
import org.warp.picalculator.math.MathematicalSymbols;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.functions.AnteriorFunction;
import org.warp.picalculator.math.functions.Function;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.functions.FunctionMultipleValues;
import org.warp.picalculator.math.functions.FunctionTwoValues;
import org.warp.picalculator.math.functions.Variable;
import org.warp.picalculator.math.functions.Variable.VariableValue;
import org.warp.picalculator.math.functions.equations.Equation;
import org.warp.picalculator.math.functions.Number;
2016-11-02 21:56:40 +01:00
2016-12-04 22:22:16 +01:00
public class MathInputScreen extends Screen {
2016-09-02 20:32:37 +02:00
public volatile String equazioneCorrente = "";
public volatile String nuovaEquazione = "";
public volatile int caretPos = 0;
public volatile boolean showCaret = true;
public volatile float showCaretDelta = 0f;
2017-01-17 22:32:40 +01:00
public Calculator calc;
2016-09-02 20:32:37 +02:00
public boolean autoscroll;
public int scrollX = 0;
2016-09-02 20:32:37 +02:00
public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto
boolean mustRefresh = true;
boolean afterDoNextStep = false;
2016-12-04 22:22:16 +01:00
public MathInputScreen() {
2016-09-02 20:32:37 +02:00
super();
canBeInHistory = true;
2017-01-16 17:57:09 +01:00
calc = new Calculator();
2016-09-02 20:32:37 +02:00
}
2016-09-02 20:32:37 +02:00
@Override
public void created() throws InterruptedException {
2016-09-02 20:32:37 +02:00
}
@Override
public void init() throws InterruptedException {
2016-10-02 16:01:41 +02:00
/* Fine caricamento */
2016-09-02 20:32:37 +02:00
2016-10-02 16:01:41 +02:00
// Parentesi f = new
// Parentesi("(â’¶(2X)*3Y)/(5Z^2)+(â’¶(11A)*13B)/(7CZ)=19XZ");
// PARENTESI CON CALCOLI
// Funzione f = new Sottrazione(new Somma(new Parentesi("â’¶9/2+â’¶7/2",
// "").calcola(), new Termine("3.5")), new
// Parentesi("3*2√14","").calcola());
// PARENTESI CON DUE NUMERI FRAZIONALI COMPLETI CON INCOGNITE:
// Funzione f = new
// Parentesi("(â’¶(2X)*3Y)/(5Z^2)+(â’¶(11A)*13B)/(7CZ)", "");
// PARENTESI CON DUE NUMERI FRAZIONALI DISALLINEATI GRAFICAMENTE:
// Funzione f = new Parentesi("((5^2-1)/2)/5-5/(5/2)=2", "");
// TERMINE DI PROVA COMPLETO:
// Funzione f = new Termine(new NumeroAvanzato(new Rational(3, 2),
// new Rational(7, 1), new Incognite(new Incognita('X',
// Rational.ONE)), new Incognite(new Incognita('Y', Rational.ONE)),
// new Incognite(new Incognita('z', Rational.ONE))));
// PARENTESI REALISTICA CON INCOGNITE:
// Funzione f = new Equazione(new
// Parentesi("X^2+(MX-M+4)^2-4X-4(MX-M+4)^2+7", ""), new
// Termine("0"));
// POTENZA:
// Funzione f = new Parentesi("(MX-M+4)^2", "");
// NUMERO SEMPLICE LUNGO:
// Funzione f = new Parentesi("-1219999799999996934.42229", "");
// :
// Funzione f = new Parentesi("5Y+XY=2", "")
2016-09-02 20:32:37 +02:00
// calcola("((5^2+3√(100/0.1))+Ⓐ(7)+9/15*2√(26/2))/21");
2017-01-17 22:32:40 +01:00
calc.init();
2016-09-02 20:32:37 +02:00
// interpreta("{(5X*(15X/3X))+(25X/(5X*(15X/3X)))=15{X=5"); //TODO RIMUOVERE
2016-10-02 16:01:41 +02:00
// long start = System.nanoTime();
// Termine result =
// Calculator.calcolarisultato("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21");
// long end = System.nanoTime();
// long timeElapsed = end-start;
// System.out.println("RESULT: " + result);
// System.out.println("DECIMAl RESULT: " +
// result.getTerm().toBigDecimal());
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
//
//
// start = System.nanoTime();
// RisultatoEquazione eresult =
// Calculator.calcolaequazione("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21=(175*(2√7)+3*(2√13))/105");
// end = System.nanoTime();
// timeElapsed = end-start;
// System.out.println("Is an equation: " + eresult.isAnEquation);
// System.out.println("L-R: " + eresult.LR);
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
2016-09-02 20:32:37 +02:00
}
public void interpreta(boolean temporary) throws Error {
final String eqn = nuovaEquazione;
if (!temporary) {
equazioneCorrente = eqn;
}
2017-01-17 22:32:40 +01:00
calc.parseInputString(eqn);
2016-09-02 20:32:37 +02:00
}
2016-09-02 20:32:37 +02:00
@Override
public void beforeRender(float dt) {
showCaretDelta += dt;
if (showCaretDelta >= 0.5f) {
mustRefresh = true;
showCaret = !showCaret;
showCaretDelta = 0f;
}
if (caretPos > nuovaEquazione.length()) {
caretPos = nuovaEquazione.length();
}
if (DisplayManager.error == null) {
DisplayManager.renderer.glClearColor(0xFFc5c2af);
} else {
DisplayManager.renderer.glClearColor(0xFFDC3C32);
}
2016-09-02 20:32:37 +02:00
}
private static final BinaryFont fontBig = Utils.getFont(false);
@Override
public void renderStatusbar() {
Renderer renderer = DisplayManager.renderer;
renderer.glColor3f(1, 1, 1);
final int pos = 2;
final int spacersNumb = 1;
int skinN = 0;
if (calc.exactMode) {
skinN = 22;
} else {
skinN = 21;
}
renderer.glFillRect(2 + 18 * pos + 2 * spacersNumb, 2, 16, 16, 16 * skinN, 16 * 0, 16, 16);
}
2016-09-02 20:32:37 +02:00
@Override
public void render() {
fontBig.use(DisplayManager.engine);
final int textColor = 0xFF000000;
final int padding = 4;
DisplayManager.renderer.glColor(textColor);
final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione.substring(0, caretPos)).length() * (fontBig.getCharacterWidth() + 1);
2016-12-04 22:22:16 +01:00
final String inputTextWithoutCaret = MathematicalSymbols.getGraphicRepresentation(nuovaEquazione);
final boolean tooLongI = padding + fontBig.getStringWidth(nuovaEquazione) + padding >= Main.screenSize[0];
int scrollI = 0;
if (tooLongI) {
scrollI = -scrollX;
if (-scrollI >= Main.screenSize[0]) {
scrollI += Main.screenSize[0];
} else {
scrollI = 0;
}
}
DisplayManager.renderer.glDrawStringLeft(padding + scrollI, padding + 20, inputTextWithoutCaret);
2016-12-04 22:22:16 +01:00
if (showCaret) {
DisplayManager.renderer.glDrawStringLeft(padding + scrollI + caretRealPos, padding + 20, "|");
2016-12-04 22:22:16 +01:00
}
if (tooLongI) {
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, padding + 20, fontBig.getCharacterHeight(), Main.screenSize[0]);
DisplayManager.renderer.glColor(textColor);
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, padding + 20 + fontBig.getCharacterHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
}
2017-01-17 22:32:40 +01:00
if (calc.f != null) {
2016-10-02 16:01:41 +02:00
int topSpacing = 0;
final Iterator<Function> iter = calc.f.iterator();
while (iter.hasNext()) {
final Function fnc = iter.next();
try {
final boolean tooLong = padding + fnc.getWidth() + padding >= Main.screenSize[0];
int scrollA = 0;
if (tooLong) {
scrollA = -scrollX;
if (-scrollA >= Main.screenSize[0]) {
scrollA += Main.screenSize[0];
} else {
scrollA = 0;
}
}
final int y = padding + 20 + padding + fontBig.getCharacterHeight() + 1 + topSpacing;
fnc.draw(padding + scrollA, y);
if (tooLong) {
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, y, fnc.getHeight(), Main.screenSize[0]);
DisplayManager.renderer.glColor(textColor);
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, y + fnc.getHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
}
} catch (final NullPointerException e) {
iter.remove();
}
topSpacing += fnc.getHeight() + 2;
2016-10-02 16:01:41 +02:00
}
}
2017-01-17 22:32:40 +01:00
if (calc.f2 != null) {
int bottomSpacing = 0;
for (final Function f : calc.f2) {
bottomSpacing += f.getHeight() + 2;
f.draw(DisplayManager.engine.getWidth() - 2 - f.getWidth(), DisplayManager.engine.getHeight() - bottomSpacing);
}
2017-01-17 22:32:40 +01:00
if (calc.resultsCount > 1 && calc.resultsCount != calc.f2.size()) {
final String resultsCountText = calc.resultsCount + " total results".toUpperCase();
DisplayManager.renderer.glColor(0xFF9AAEA0);
Utils.getFont(true).use(DisplayManager.engine);
bottomSpacing += fontBig.getCharacterHeight() + 2;
DisplayManager.renderer.glDrawStringRight(DisplayManager.engine.getWidth() - 2, DisplayManager.engine.getHeight() - bottomSpacing, resultsCountText);
2016-11-02 21:56:40 +01:00
}
}
2016-09-02 20:32:37 +02:00
}
@Override
public boolean mustBeRefreshed() {
if (mustRefresh) {
mustRefresh = false;
return true;
} else {
return false;
}
}
@Override
public boolean keyPressed(Key k) {
switch (k) {
case SIMPLIFY:
if (nuovaEquazione.length() > 0) {
2017-01-16 17:57:09 +01:00
if (!afterDoNextStep) {
try {
2017-01-16 17:57:09 +01:00
try {
interpreta(true);
showVariablesDialog(() -> {
equazioneCorrente = nuovaEquazione;
calc.f2 = calc.f;
afterDoNextStep = true;
2017-02-02 12:49:31 +01:00
simplify();
2017-01-16 17:57:09 +01:00
});
} catch (final Exception ex) {
if (Utils.debugOn) {
2017-01-16 17:57:09 +01:00
ex.printStackTrace();
}
2017-01-16 17:57:09 +01:00
throw new Error(Errors.SYNTAX_ERROR);
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
2017-01-16 17:57:09 +01:00
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
2017-01-16 17:57:09 +01:00
System.err.println(e.id);
}
2017-01-16 17:57:09 +01:00
} else {
2017-02-02 12:49:31 +01:00
simplify();
}
2016-09-02 20:32:37 +02:00
}
return true;
case SOLVE:
if (DisplayManager.error != null) {
2016-09-02 20:32:37 +02:00
Utils.debug.println("Resetting after error...");
DisplayManager.error = null;
equazioneCorrente = null;
2017-01-17 22:32:40 +01:00
calc.f = null;
calc.f2 = null;
calc.resultsCount = 0;
2016-09-02 20:32:37 +02:00
return true;
} else {
try {
2016-09-02 20:32:37 +02:00
try {
if (afterDoNextStep) {
2017-02-02 12:49:31 +01:00
simplify();
} else {
if (nuovaEquazione != equazioneCorrente && nuovaEquazione.length() > 0) {
changeEquationScreen();
2017-01-16 17:57:09 +01:00
interpreta(true);
showVariablesDialog(() -> {
equazioneCorrente = nuovaEquazione;
solve();
});
}
2016-09-02 20:32:37 +02:00
}
} catch (final Exception ex) {
if (Utils.debugOn) {
ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR);
2016-09-02 20:32:37 +02:00
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
System.err.println(e.id);
2016-09-02 20:32:37 +02:00
}
return true;
}
case NUM0:
typeChar("0");
return true;
case NUM1:
typeChar("1");
return true;
case NUM2:
typeChar("2");
return true;
case NUM3:
typeChar("3");
return true;
case NUM4:
typeChar("4");
return true;
case NUM5:
typeChar("5");
return true;
case NUM6:
typeChar("6");
return true;
case NUM7:
typeChar("7");
return true;
case NUM8:
typeChar("8");
return true;
case NUM9:
typeChar("9");
return true;
case PLUS:
typeChar("+");
return true;
case MINUS:
typeChar("-");
return true;
case PLUS_MINUS:
typeChar("±");
return true;
2016-09-02 20:32:37 +02:00
case MULTIPLY:
typeChar("*");
return true;
case DIVIDE:
typeChar("/");
return true;
case PARENTHESIS_OPEN:
typeChar("(");
return true;
case PARENTHESIS_CLOSE:
typeChar(")");
return true;
case DOT:
typeChar(".");
return true;
case EQUAL:
typeChar("=");
return true;
case SQRT:
typeChar("â’¶");
return true;
case ROOT:
typeChar("√");
return true;
case POWER_OF_2:
typeChar(MathematicalSymbols.POWER + "2");
2016-09-02 20:32:37 +02:00
return true;
case POWER_OF_x:
2016-12-04 22:22:16 +01:00
typeChar(MathematicalSymbols.POWER);
2016-09-02 20:32:37 +02:00
return true;
2017-01-16 17:57:09 +01:00
case PI:
typeChar(MathematicalSymbols.PI);
return true;
case LETTER_X:
typeChar(MathematicalSymbols.variables()[23]);
return true;
case LETTER_Y:
typeChar(MathematicalSymbols.variables()[24]);
return true;
2016-12-04 22:22:16 +01:00
case SINE:
typeChar(MathematicalSymbols.SINE);
return true;
case COSINE:
typeChar(MathematicalSymbols.COSINE);
return true;
case TANGENT:
typeChar(MathematicalSymbols.TANGENT);
return true;
case ARCSINE:
typeChar(MathematicalSymbols.ARC_SINE);
return true;
case ARCCOSINE:
typeChar(MathematicalSymbols.ARC_COSINE);
return true;
case ARCTANGENT:
typeChar(MathematicalSymbols.ARC_TANGENT);
return true;
2016-09-02 20:32:37 +02:00
case DELETE:
if (nuovaEquazione.length() > 0) {
if (caretPos > 0) {
caretPos -= 1;
nuovaEquazione = nuovaEquazione.substring(0, caretPos) + nuovaEquazione.substring(caretPos + 1, nuovaEquazione.length());
2016-09-02 20:32:37 +02:00
} else {
nuovaEquazione = nuovaEquazione.substring(1);
}
try {
interpreta(true);
} catch (final Error e) {}
2016-09-02 20:32:37 +02:00
}
afterDoNextStep = false;
2016-09-02 20:32:37 +02:00
return true;
case LEFT:
if (caretPos > 0) {
caretPos -= 1;
} else {
caretPos = nuovaEquazione.length();
2016-09-02 20:32:37 +02:00
}
scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
2016-09-02 20:32:37 +02:00
return true;
case RIGHT:
if (caretPos < nuovaEquazione.length()) {
caretPos += 1;
} else {
caretPos = 0;
2016-09-02 20:32:37 +02:00
}
scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
2016-09-02 20:32:37 +02:00
return true;
case RESET:
if (DisplayManager.error != null) {
2016-09-02 20:32:37 +02:00
Utils.debug.println("Resetting after error...");
DisplayManager.error = null;
2016-09-02 20:32:37 +02:00
return true;
} else {
caretPos = 0;
nuovaEquazione = "";
afterDoNextStep = false;
2017-01-17 22:32:40 +01:00
if (calc.f != null) {
2017-02-02 12:49:31 +01:00
calc.f = new ArrayList<>();
2016-12-03 16:37:22 +01:00
}
2016-09-02 20:32:37 +02:00
return true;
}
case SURD_MODE:
2017-01-16 17:57:09 +01:00
calc.exactMode = !calc.exactMode;
if (calc.exactMode == false) {
2017-01-17 22:32:40 +01:00
calc.f2 = solveExpression(calc.f2);
2017-01-16 17:57:09 +01:00
} else {
equazioneCorrente = "";
Keyboard.keyPressed(Key.SOLVE);
}
return true;
2016-09-02 20:32:37 +02:00
case debug1:
DisplayManager.INSTANCE.setScreen(new EmptyScreen());
2016-09-02 20:32:37 +02:00
return true;
case HISTORY_BACK:
if (DisplayManager.INSTANCE.canGoBack()) {
if (equazioneCorrente != null && equazioneCorrente.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) {
nuovaEquazione = equazioneCorrente;
try {
interpreta(true);
} catch (final Error e) {}
}
}
return false;
case HISTORY_FORWARD:
if (DisplayManager.INSTANCE.canGoForward()) {
if (equazioneCorrente != null && equazioneCorrente.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) {
nuovaEquazione = equazioneCorrente;
try {
interpreta(true);
} catch (final Error e) {}
}
}
return false;
2017-01-16 17:57:09 +01:00
case debug_DEG:
if (calc.angleMode.equals(AngleMode.DEG) == false) {
calc.angleMode = AngleMode.DEG;
return true;
}
return false;
case debug_RAD:
if (calc.angleMode.equals(AngleMode.RAD) == false) {
calc.angleMode = AngleMode.RAD;
return true;
}
return false;
case debug_GRA:
if (calc.angleMode.equals(AngleMode.GRA) == false) {
calc.angleMode = AngleMode.GRA;
return true;
}
return false;
case DRG_CYCLE:
if (calc.angleMode.equals(AngleMode.DEG) == true) {
calc.angleMode = AngleMode.RAD;
} else if (calc.angleMode.equals(AngleMode.RAD) == true) {
calc.angleMode = AngleMode.GRA;
} else {
calc.angleMode = AngleMode.DEG;
}
return true;
2016-09-02 20:32:37 +02:00
default:
return false;
}
}
2017-01-16 17:57:09 +01:00
private ArrayList<Function> solveExpression(ArrayList<Function> f22) {
try {
try {
return calc.solveExpression(f22);
} catch (final Exception ex) {
2017-01-16 17:57:09 +01:00
if (Utils.debugOn) {
ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR);
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
2017-01-16 17:57:09 +01:00
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
2017-01-16 17:57:09 +01:00
System.err.println(e.id);
}
return null;
}
2017-02-02 12:49:31 +01:00
protected void simplify() {
2017-01-16 17:57:09 +01:00
try {
try {
showVariablesDialog();
ArrayList<Function> results = new ArrayList<>();
final ArrayList<Function> partialResults = new ArrayList<>();
for (final Function f : calc.f2) {
2017-01-16 17:57:09 +01:00
if (f instanceof Equation) {
DisplayManager.INSTANCE.setScreen(new SolveEquationScreen(this));
2017-01-16 17:57:09 +01:00
} else {
results.add(f);
for (final Function itm : results) {
2017-01-16 17:57:09 +01:00
if (itm.isSolved() == false) {
final List<Function> dt = itm.solveOneStep();
2017-01-16 17:57:09 +01:00
partialResults.addAll(dt);
} else {
partialResults.add(itm);
}
}
2017-01-17 22:32:40 +01:00
results = new ArrayList<>(partialResults);
2017-01-16 17:57:09 +01:00
partialResults.clear();
}
}
2017-01-16 17:57:09 +01:00
if (results.size() == 0) {
2017-01-17 22:32:40 +01:00
calc.resultsCount = 0;
2017-01-16 17:57:09 +01:00
} else {
2017-01-17 22:32:40 +01:00
calc.resultsCount = results.size();
2017-01-16 17:57:09 +01:00
Collections.reverse(results);
// add elements to al, including duplicates
final Set<Function> hs = new LinkedHashSet<>();
2017-01-16 17:57:09 +01:00
hs.addAll(results);
results.clear();
results.addAll(hs);
2017-01-17 22:32:40 +01:00
calc.f2 = results;
for (final Function rf : calc.f2) {
2017-01-16 17:57:09 +01:00
rf.generateGraphics();
}
}
2017-02-02 12:49:31 +01:00
Utils.debug.println(calc.f2.toString());
} catch (final Exception ex) {
2017-01-16 17:57:09 +01:00
if (Utils.debugOn) {
ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR);
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
2017-01-16 17:57:09 +01:00
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
2017-01-16 17:57:09 +01:00
System.err.println(e.id);
}
}
protected void solve() {
try {
try {
for (final Function f : calc.f) {
2017-01-16 17:57:09 +01:00
if (f instanceof Equation) {
DisplayManager.INSTANCE.setScreen(new SolveEquationScreen(this));
2017-01-16 17:57:09 +01:00
return;
}
}
final ArrayList<Function> results = solveExpression(calc.f);
2017-01-16 17:57:09 +01:00
if (results.size() == 0) {
2017-01-17 22:32:40 +01:00
calc.resultsCount = 0;
2017-01-16 17:57:09 +01:00
} else {
2017-01-17 22:32:40 +01:00
calc.resultsCount = results.size();
2017-01-16 17:57:09 +01:00
Collections.reverse(results);
// add elements to al, including duplicates
final Set<Function> hs = new LinkedHashSet<>();
2017-01-16 17:57:09 +01:00
hs.addAll(results);
results.clear();
results.addAll(hs);
2017-01-17 22:32:40 +01:00
calc.f2 = results;
for (final Function rf : calc.f2) {
2017-01-16 17:57:09 +01:00
rf.generateGraphics();
}
}
} catch (final Exception ex) {
2017-01-16 17:57:09 +01:00
if (Utils.debugOn) {
ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR);
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
2017-01-16 17:57:09 +01:00
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
2017-01-16 17:57:09 +01:00
System.err.println(e.id);
}
}
2016-11-02 21:56:40 +01:00
private void changeEquationScreen() {
if (equazioneCorrente != null && equazioneCorrente.length() > 0) {
final MathInputScreen cloned = clone();
2016-11-02 21:56:40 +01:00
cloned.caretPos = cloned.equazioneCorrente.length();
cloned.nuovaEquazione = cloned.equazioneCorrente;
cloned.scrollX = fontBig.getStringWidth(cloned.equazioneCorrente);
try {
cloned.interpreta(true);
} catch (final Error e) {}
DisplayManager.INSTANCE.replaceScreen(cloned);
initialized = false;
DisplayManager.INSTANCE.setScreen(this);
2016-11-02 21:56:40 +01:00
}
}
2016-09-02 20:32:37 +02:00
public void typeChar(String chr) {
final int len = chr.length();
nuovaEquazione = nuovaEquazione.substring(0, caretPos) + chr + nuovaEquazione.substring(caretPos, nuovaEquazione.length());
caretPos += len;
scrollX = fontBig.getStringWidth(nuovaEquazione.substring(0, caretPos) + "|||");
2016-09-02 20:32:37 +02:00
showCaret = true;
showCaretDelta = 0L;
afterDoNextStep = false;
try {
interpreta(true);
} catch (final Error e) {}
2016-11-02 21:56:40 +01:00
// f.clear(); //TODO: I removed this line to prevent input blanking when pressing EQUALS button and cloning this screen, but I must see why I created this part of code.
2016-09-02 20:32:37 +02:00
}
@Override
public boolean keyReleased(Key k) {
return false;
}
2017-01-17 22:32:40 +01:00
public void showVariablesDialog() {
showVariablesDialog(null);
}
2017-01-16 17:57:09 +01:00
public void showVariablesDialog(final Runnable runnable) {
final Thread ct = new Thread(() -> {
final ArrayList<Function> variablesInFunctions = getVariables(calc.f.toArray(new Function[calc.f.size()]));
for (final VariableValue f : calc.variablesValues) {
2017-01-16 17:57:09 +01:00
if (variablesInFunctions.contains(f.v)) {
variablesInFunctions.remove(f.v);
}
}
2017-01-16 17:57:09 +01:00
boolean cancelled = false;
for (final Function f : variablesInFunctions) {
final ChooseVariableValueScreen cvs = new ChooseVariableValueScreen(this, new VariableValue((Variable) f, new Number(calc, 0)));
DisplayManager.INSTANCE.setScreen(cvs);
2017-01-16 17:57:09 +01:00
try {
while (DisplayManager.screen == cvs) {
2017-01-16 17:57:09 +01:00
Utils.debug.println(Thread.currentThread().getName());
Thread.sleep(200);
}
} catch (final InterruptedException e) {}
2017-01-16 17:57:09 +01:00
if (cvs.resultNumberValue == null) {
cancelled = true;
break;
} else {
2017-01-17 22:32:40 +01:00
final int is = calc.variablesValues.size();
2017-01-16 17:57:09 +01:00
for (int i = 0; i < is; i++) {
2017-01-17 22:32:40 +01:00
if (calc.variablesValues.get(i).v == f) {
calc.variablesValues.remove(i);
2017-01-16 17:57:09 +01:00
}
}
2017-01-17 22:32:40 +01:00
calc.variablesValues.add(new VariableValue((Variable) f, (Number) cvs.resultNumberValue));
2017-01-16 17:57:09 +01:00
}
}
if (!cancelled) {
2017-01-17 22:32:40 +01:00
if (runnable != null) {
runnable.run();
}
2017-01-16 17:57:09 +01:00
}
});
ct.setName("Variables user-input queue thread");
ct.setPriority(Thread.MIN_PRIORITY);
ct.setDaemon(true);
ct.start();
}
2017-01-16 17:57:09 +01:00
private ArrayList<Function> getVariables(Function[] fncs) {
final ArrayList<Function> res = new ArrayList<>();
for (final Function f : fncs) {
2017-01-16 17:57:09 +01:00
if (f instanceof FunctionTwoValues) {
res.addAll(getVariables(new Function[] { ((FunctionTwoValues) f).getVariable1(), ((FunctionTwoValues) f).getVariable2() }));
2017-01-16 17:57:09 +01:00
} else if (f instanceof FunctionMultipleValues) {
res.addAll(getVariables(((FunctionMultipleValues) f).getVariables()));
2017-01-16 17:57:09 +01:00
} else if (f instanceof AnteriorFunction) {
res.addAll(getVariables(new Function[] { ((AnteriorFunction) f).getVariable() }));
2017-01-16 17:57:09 +01:00
} else if (f instanceof Variable) {
if (!res.contains(f)) {
res.add(f);
}
}
}
return res;
}
2016-11-02 21:56:40 +01:00
@Override
2016-12-04 22:22:16 +01:00
public MathInputScreen clone() {
final MathInputScreen es = this;
final MathInputScreen es2 = new MathInputScreen();
es2.scrollX = es.scrollX;
2016-11-02 21:56:40 +01:00
es2.nuovaEquazione = es.nuovaEquazione;
es2.equazioneCorrente = es.equazioneCorrente;
es2.showCaret = es.showCaret;
es2.showCaretDelta = es.showCaretDelta;
es2.caretPos = es.caretPos;
2017-01-17 22:32:40 +01:00
// es2.calc.f = Utils.cloner.deepClone(es.calc.f);
// es2.calc.f2 = Utils.cloner.deepClone(es.calc.f2);
// es2.calc.resultsCount = es.calc.resultsCount;
2016-11-02 21:56:40 +01:00
es2.autoscroll = es.autoscroll;
es2.errorLevel = es.errorLevel;
es2.mustRefresh = es.mustRefresh;
es2.afterDoNextStep = es.afterDoNextStep;
2017-01-17 22:32:40 +01:00
// es2.calc.variablesValues = Utils.cloner.deepClone(es.calc.variablesValues);
es2.calc = Utils.cloner.deepClone(es.calc);
2016-11-02 21:56:40 +01:00
return es2;
}
2016-09-02 20:32:37 +02:00
}