2017-01-22 13:46:38 +01:00
package org.warp.picalculator.gui.screens ;
2016-09-02 20:32:37 +02:00
2017-03-26 22:44:09 +02:00
import java.io.IOException ;
2016-09-02 20:32:37 +02:00
import java.io.PrintWriter ;
import java.io.StringWriter ;
2017-01-16 17:57:09 +01:00
import java.util.List ;
2016-09-02 20:32:37 +02:00
2016-09-12 16:30:51 +02:00
import org.warp.picalculator.Error ;
import org.warp.picalculator.Errors ;
2017-10-17 22:49:21 +02:00
import org.warp.picalculator.StaticVars ;
2016-09-02 20:32:37 +02:00
import org.warp.picalculator.Utils ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.device.Keyboard ;
2016-09-19 18:48:27 +02:00
import org.warp.picalculator.device.Keyboard.Key ;
2017-01-31 22:29:49 +01:00
import org.warp.picalculator.gui.DisplayManager ;
2017-05-16 22:02:44 +02:00
import org.warp.picalculator.gui.expression.InputContext ;
2017-04-12 13:04:35 +02:00
import org.warp.picalculator.gui.expression.blocks.Block ;
import org.warp.picalculator.gui.expression.blocks.BlockContainer ;
2017-03-26 22:44:09 +02:00
import org.warp.picalculator.gui.expression.containers.InputContainer ;
import org.warp.picalculator.gui.expression.containers.NormalInputContainer ;
import org.warp.picalculator.gui.expression.containers.NormalOutputContainer ;
import org.warp.picalculator.gui.expression.containers.OutputContainer ;
2017-02-02 10:30:45 +01:00
import org.warp.picalculator.gui.graphicengine.BinaryFont ;
2017-01-31 22:29:49 +01:00
import org.warp.picalculator.gui.graphicengine.Renderer ;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.AngleMode ;
2017-02-14 20:02:03 +01:00
import org.warp.picalculator.math.Function ;
import org.warp.picalculator.math.FunctionDynamic ;
import org.warp.picalculator.math.FunctionOperator ;
2017-05-16 22:02:44 +02:00
import org.warp.picalculator.math.FunctionSingle ;
import org.warp.picalculator.math.MathContext ;
2017-12-22 22:39:58 +01:00
import org.warp.picalculator.math.MathSolver ;
2016-11-25 22:40:43 +01:00
import org.warp.picalculator.math.MathematicalSymbols ;
2017-05-16 22:02:44 +02:00
import org.warp.picalculator.math.functions.Expression ;
import org.warp.picalculator.math.functions.Number ;
2017-01-16 17:57:09 +01:00
import org.warp.picalculator.math.functions.Variable ;
import org.warp.picalculator.math.functions.Variable.VariableValue ;
2017-04-10 22:50:43 +02:00
import org.warp.picalculator.math.parser.MathParser ;
2017-05-16 22:02:44 +02:00
import it.unimi.dsi.fastutil.objects.ObjectArrayList ;
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
2017-11-19 12:55:48 +01:00
private static final BinaryFont fontBig = Utils . getFont ( false ) ;
2017-02-14 20:02:03 +01:00
public MathContext calc ;
2017-05-16 22:02:44 +02:00
public InputContext ic ;
2017-03-26 22:44:09 +02:00
public InputContainer userInput ;
public OutputContainer result ;
2016-09-02 20:32:37 +02:00
public int errorLevel = 0 ; // 0 = nessuno, 1 = risultato, 2 = tutto
2017-11-19 12:55:48 +01:00
private boolean computingResult = false ;
private Thread computingThread ;
private int computingAnimationIndex = 0 ;
private double computingAnimationElapsedTime = 0 ;
private double computingElapsedTime = 0 ;
private boolean computingBreakTipVisible = false ;
2016-09-02 20:32:37 +02:00
boolean mustRefresh = true ;
2017-12-20 18:07:11 +01:00
private int currentStep = 0 ;
2017-01-31 22:29:49 +01:00
2016-12-04 22:22:16 +01:00
public MathInputScreen ( ) {
2016-09-02 20:32:37 +02:00
super ( ) ;
canBeInHistory = true ;
}
2017-01-31 22:29:49 +01:00
2016-09-02 20:32:37 +02:00
@Override
public void created ( ) throws InterruptedException {
2017-05-16 22:02:44 +02:00
ic = new InputContext ( ) ;
2017-03-26 22:44:09 +02:00
calc = new MathContext ( ) ;
2017-04-10 22:50:43 +02:00
2017-03-26 22:44:09 +02:00
try {
2017-11-19 12:55:48 +01:00
BlockContainer . initializeFonts ( DisplayManager . INSTANCE . engine . loadFont ( " norm " ) , DisplayManager . INSTANCE . engine . loadFont ( " smal " ) ) ;
2017-04-10 22:50:43 +02:00
} catch ( final IOException e ) {
2017-03-26 22:44:09 +02:00
e . printStackTrace ( ) ;
System . exit ( 1 ) ;
}
2017-04-10 22:50:43 +02:00
2017-05-16 22:02:44 +02:00
userInput = new NormalInputContainer ( ic ) ;
2017-03-26 22:44:09 +02:00
result = new NormalOutputContainer ( ) ;
2017-04-10 22:50:43 +02:00
2017-03-26 22:44:09 +02:00
calc . init ( ) ;
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
}
2017-04-10 22:50:43 +02:00
2016-09-02 20:32:37 +02:00
@Override
public void beforeRender ( float dt ) {
2017-09-24 18:47:30 +02:00
if ( DisplayManager . INSTANCE . error = = null ) {
DisplayManager . INSTANCE . renderer . glClearColor ( 0xFFc5c2af ) ;
2016-11-25 22:40:43 +01:00
} else {
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . renderer . glClearColor ( 0xFFDC3C32 ) ;
2016-11-25 22:40:43 +01:00
}
2017-03-26 22:44:09 +02:00
if ( userInput . beforeRender ( dt ) ) {
mustRefresh = true ;
}
2017-11-19 12:55:48 +01:00
if ( computingResult ) {
computingElapsedTime + = dt ;
computingAnimationElapsedTime + = dt ;
if ( computingAnimationElapsedTime > 0 . 1 ) {
computingAnimationElapsedTime - = 0 . 1 ;
computingAnimationIndex = ( computingAnimationIndex + 1 ) % 16 ;
mustRefresh = true ;
}
if ( computingElapsedTime > 5 ) {
computingBreakTipVisible = true ;
}
} else {
computingElapsedTime = 0 ;
computingAnimationElapsedTime = 0 ;
computingAnimationIndex = 0 ;
computingBreakTipVisible = false ;
}
2016-09-02 20:32:37 +02:00
}
2017-11-19 12:55:48 +01:00
@Override
public void render ( ) {
final Renderer renderer = DisplayManager . INSTANCE . renderer ;
fontBig . use ( DisplayManager . INSTANCE . engine ) ;
final int textColor = 0xFF000000 ;
final int padding = 4 ;
renderer . glColor ( textColor ) ;
2016-09-02 20:32:37 +02:00
2017-11-19 12:55:48 +01:00
userInput . draw ( DisplayManager . INSTANCE . engine , renderer , padding , padding + 20 ) ;
if ( computingResult ) {
renderer . glColor3f ( 1 , 1 , 1 ) ;
final int leftX = 208 ;
final int leftY = 16 ;
final int size = 32 ;
final int posY = computingAnimationIndex % 2 ;
final int posX = ( computingAnimationIndex - posY ) / 2 ;
renderer . glFillRect ( DisplayManager . INSTANCE . engine . getWidth ( ) - size - 4 , DisplayManager . INSTANCE . engine . getHeight ( ) - size - 4 , size , size , leftX + size * posX , leftY + size * posY , size , size ) ;
if ( computingBreakTipVisible ) {
Utils . getFont ( false ) . use ( DisplayManager . INSTANCE . engine ) ;
renderer . glColor3f ( 0 . 75f , 0 , 0 ) ;
renderer . glDrawStringRight ( DisplayManager . INSTANCE . engine . getWidth ( ) - 4 - size - 4 , DisplayManager . INSTANCE . engine . getHeight ( ) - size / 2 - renderer . getCurrentFont ( ) . getCharacterHeight ( ) / 2 - 4 , " Press (=) to stop " ) ;
}
} else {
if ( ! result . isContentEmpty ( ) ) {
result . draw ( DisplayManager . INSTANCE . engine , renderer , DisplayManager . INSTANCE . engine . getWidth ( ) - result . getWidth ( ) - 2 , DisplayManager . INSTANCE . engine . getHeight ( ) - result . getHeight ( ) - 2 ) ;
}
}
}
2017-01-31 22:29:49 +01:00
2017-01-22 13:46:38 +01:00
@Override
public void renderStatusbar ( ) {
2017-09-24 18:47:30 +02:00
final Renderer renderer = DisplayManager . INSTANCE . renderer ;
2017-01-31 22:29:49 +01:00
renderer . glColor3f ( 1 , 1 , 1 ) ;
final int pos = 2 ;
final int spacersNumb = 1 ;
2017-01-22 13:46:38 +01:00
int skinN = 0 ;
if ( calc . exactMode ) {
skinN = 22 ;
} else {
skinN = 21 ;
}
2017-01-31 22:29:49 +01:00
renderer . glFillRect ( 2 + 18 * pos + 2 * spacersNumb , 2 , 16 , 16 , 16 * skinN , 16 * 0 , 16 , 16 ) ;
2017-01-22 13:46:38 +01:00
}
2017-01-31 22:29:49 +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 ) {
2017-06-09 22:47:30 +02:00
Utils . out . println ( 1 , k . toString ( ) ) ;
2016-09-02 20:32:37 +02:00
switch ( k ) {
2017-05-05 22:27:11 +02:00
case OK :
userInput . toggleExtra ( ) ;
2017-03-26 22:44:09 +02:00
mustRefresh = true ;
2016-09-02 20:32:37 +02:00
return true ;
2016-11-25 22:40:43 +01:00
case HISTORY_BACK :
2017-05-05 22:27:11 +02:00
if ( userInput . isExtraOpened ( ) ) {
userInput . closeExtra ( ) ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
mustRefresh = true ;
2017-01-16 17:57:09 +01:00
return true ;
}
2017-05-05 22:27:11 +02:00
default :
if ( userInput . isExtraOpened ( ) & & userInput . getExtraKeyboardEventListener ( ) . keyPressed ( k ) ) {
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-01-16 17:57:09 +01:00
return true ;
} else {
2017-12-20 18:07:11 +01:00
final boolean step = k = = Key . STEP ;
2017-05-05 22:27:11 +02:00
switch ( k ) {
case STEP :
2017-12-20 18:07:11 +01:00
currentStep + + ;
2017-05-05 22:27:11 +02:00
case SIMPLIFY :
2017-12-20 18:07:11 +01:00
if ( ! step ) currentStep = 0 ;
2017-09-24 18:47:30 +02:00
if ( DisplayManager . INSTANCE . error ! = null ) {
2017-05-05 22:27:11 +02:00
//TODO: make the error management a global API rather than being relegated to this screen.
2017-06-09 22:47:30 +02:00
Utils . out . println ( 1 , " Resetting after error... " ) ;
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . error = null ;
2017-05-05 22:27:11 +02:00
calc . f = null ;
calc . f2 = null ;
calc . resultsCount = 0 ;
return true ;
} else {
2017-11-19 12:55:48 +01:00
if ( ! computingResult ) {
computingResult = true ;
computingThread = new Thread ( ( ) - > {
try {
try {
if ( ! userInput . isAlreadyParsed ( ) & & ! userInput . isEmpty ( ) ) {
Expression expr = MathParser . parseInput ( calc , userInput ) ;
if ( calc . f = = null | calc . f2 = = null ) {
calc . f = new ObjectArrayList < > ( ) ;
calc . f2 = new ObjectArrayList < > ( ) ;
} else {
calc . f . clear ( ) ;
calc . f2 . clear ( ) ;
}
calc . f . add ( expr ) ;
2017-12-20 18:07:11 +01:00
Utils . out . println ( 2 , " INPUT: " + expr ) ;
2017-12-22 22:39:58 +01:00
MathSolver ms = new MathSolver ( expr ) ;
ObjectArrayList < ObjectArrayList < Function > > resultSteps = ms . solveAllSteps ( ) ;
resultSteps . add ( 0 , Utils . newArrayList ( expr ) ) ;
ObjectArrayList < Function > resultExpressions = resultSteps . get ( resultSteps . size ( ) - 1 ) ;
2017-11-19 12:55:48 +01:00
for ( Function rr : resultExpressions ) {
Utils . out . println ( 1 , " RESULT: " + rr . toString ( ) ) ;
2017-06-05 22:50:33 +02:00
}
2017-11-19 12:55:48 +01:00
ObjectArrayList < ObjectArrayList < Block > > resultBlocks = MathParser . parseOutput ( calc , resultExpressions ) ;
result . setContentAsMultipleGroups ( resultBlocks ) ;
// showVariablesDialog(() -> {
// currentExpression = newExpression;
// simplify();
// });
2017-06-05 22:50:33 +02:00
}
2017-11-19 12:55:48 +01:00
} catch ( final InterruptedException ex ) {
Utils . out . println ( Utils . OUTPUTLEVEL_DEBUG_MIN , " Computing thread stopped. " ) ;
} catch ( final Exception ex ) {
if ( StaticVars . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
2017-06-09 22:47:30 +02:00
}
2017-11-19 12:55:48 +01: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 . INSTANCE . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
2017-05-05 22:27:11 +02:00
}
2017-11-19 12:55:48 +01:00
computingResult = false ;
} ) ;
computingThread . setName ( " Computing Thread " ) ;
computingThread . setDaemon ( true ) ;
computingThread . setPriority ( Thread . NORM_PRIORITY + 3 ) ;
computingThread . start ( ) ;
return true ;
} else {
if ( computingThread ! = null ) {
computingThread . interrupt ( ) ;
computingResult = false ;
return true ;
2017-05-05 22:27:11 +02:00
}
2017-11-19 12:55:48 +01:00
return false ;
2017-05-05 22:27:11 +02:00
}
}
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 ;
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_OF_TWO ) ;
return true ;
case POWER_OF_x :
typeChar ( MathematicalSymbols . POWER ) ;
return true ;
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 ;
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 ;
case DELETE :
userInput . del ( ) ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
mustRefresh = true ;
return true ;
case LEFT :
userInput . moveLeft ( ) ;
mustRefresh = true ;
return true ;
case RIGHT :
userInput . moveRight ( ) ;
mustRefresh = true ;
return true ;
case RESET :
userInput . clear ( ) ;
result . clear ( ) ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-09-24 18:47:30 +02:00
if ( DisplayManager . INSTANCE . error ! = null ) {
2017-06-09 22:47:30 +02:00
Utils . out . println ( 1 , " Resetting after error... " ) ;
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . error = null ;
2017-05-05 22:27:11 +02:00
}
return true ;
case SURD_MODE :
calc . exactMode = ! calc . exactMode ;
2017-06-09 22:47:30 +02:00
result . clear ( ) ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-06-09 22:47:30 +02:00
Keyboard . keyPressed ( Key . SIMPLIFY ) ;
2017-05-05 22:27:11 +02:00
return true ;
case debug1 :
DisplayManager . INSTANCE . setScreen ( new EmptyScreen ( ) ) ;
return true ;
case HISTORY_BACK :
2017-09-24 18:47:30 +02:00
// if (DisplayManager.INSTANCE.canGoBack()) {
// if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.INSTANCE.sessions[DisplayManager.INSTANCE.currentSession + 1] instanceof MathInputScreen) {
// newExpression = currentExpression;
// try {
// interpreta(true);
// } catch (final Error e) {}
// }
// }
2017-05-05 22:27:11 +02:00
return false ;
case HISTORY_FORWARD :
2017-09-24 18:47:30 +02:00
// if (DisplayManager.INSTANCE.canGoForward()) {
// if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.INSTANCE.sessions[DisplayManager.INSTANCE.currentSession - 1] instanceof MathInputScreen) {
// newExpression = currentExpression;
// try {
// interpreta(true);
// } catch (final Error e) {}
// }
// }
2017-05-05 22:27:11 +02:00
return false ;
case debug_DEG :
if ( calc . angleMode . equals ( AngleMode . DEG ) = = false ) {
calc . angleMode = AngleMode . DEG ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
return true ;
}
return false ;
case debug_RAD :
if ( calc . angleMode . equals ( AngleMode . RAD ) = = false ) {
calc . angleMode = AngleMode . RAD ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
return true ;
}
return false ;
case debug_GRA :
if ( calc . angleMode . equals ( AngleMode . GRA ) = = false ) {
calc . angleMode = AngleMode . GRA ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
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 ;
}
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
return true ;
default :
return false ;
}
2017-01-16 17:57:09 +01:00
}
2016-09-02 20:32:37 +02:00
}
}
2017-01-31 22:29:49 +01:00
2017-06-09 22:47:30 +02:00
@SuppressWarnings ( " unused " )
@Deprecated
2017-03-03 23:06:43 +01:00
private ObjectArrayList < Function > solveExpression ( ObjectArrayList < Function > f22 ) {
2017-06-09 22:47:30 +02:00
return null ;
/ *
2017-01-16 17:57:09 +01:00
try {
try {
return calc . solveExpression ( f22 ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2017-01-16 17:57:09 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2017-01-31 22:29:49 +01:00
} 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 " ) ;
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
}
return null ;
2017-06-09 22:47:30 +02:00
* /
2017-01-16 17:57:09 +01:00
}
2017-06-09 22:47:30 +02:00
@Deprecated
2017-02-06 21:38:17 +01:00
protected void step ( ) {
2017-06-09 22:47:30 +02:00
/ *
2017-01-16 17:57:09 +01:00
try {
try {
showVariablesDialog ( ) ;
2017-03-03 23:06:43 +01:00
ObjectArrayList < Function > results = new ObjectArrayList < > ( ) ;
final ObjectArrayList < Function > partialResults = new ObjectArrayList < > ( ) ;
2017-01-31 22:29:49 +01:00
for ( final Function f : calc . f2 ) {
2017-01-16 17:57:09 +01:00
if ( f instanceof Equation ) {
2017-01-31 22:29:49 +01:00
DisplayManager . INSTANCE . setScreen ( new SolveEquationScreen ( this ) ) ;
2017-01-16 17:57:09 +01:00
} else {
results . add ( f ) ;
2017-01-31 22:29:49 +01:00
for ( final Function itm : results ) {
2017-02-14 20:02:03 +01:00
if ( itm . isSimplified ( ) = = false ) {
final List < Function > dt = itm . simplify ( ) ;
2017-01-16 17:57:09 +01:00
partialResults . addAll ( dt ) ;
} else {
partialResults . add ( itm ) ;
}
}
2017-03-03 23:06:43 +01:00
results = new ObjectArrayList < > ( partialResults ) ;
2017-01-16 17:57:09 +01:00
partialResults . clear ( ) ;
}
}
2017-09-24 18:47:30 +02:00
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
2017-01-31 22:29:49 +01:00
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 ;
2017-01-16 17:57:09 +01:00
}
2017-06-09 22:47:30 +02:00
Utils . out . println ( 1 , calc . f2 . toString ( ) ) ;
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2017-01-16 17:57:09 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2017-01-31 22:29:49 +01:00
} 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 " ) ;
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
}
2017-06-09 22:47:30 +02:00
* /
2017-01-16 17:57:09 +01:00
}
2017-06-09 22:47:30 +02:00
@Deprecated
2017-02-06 21:38:17 +01:00
protected void simplify ( ) {
2017-06-09 22:47:30 +02:00
/ *
2017-01-16 17:57:09 +01:00
try {
try {
2017-01-31 22:29:49 +01:00
for ( final Function f : calc . f ) {
2017-01-16 17:57:09 +01:00
if ( f instanceof Equation ) {
2017-01-31 22:29:49 +01:00
DisplayManager . INSTANCE . setScreen ( new SolveEquationScreen ( this ) ) ;
2017-01-16 17:57:09 +01:00
return ;
}
}
2017-09-24 18:47:30 +02:00
2017-03-03 23:06:43 +01:00
final ObjectArrayList < 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
2017-01-31 22:29:49 +01:00
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 ;
2017-01-16 17:57:09 +01:00
}
2017-01-31 22:29:49 +01:00
} catch ( final Exception ex ) {
2017-01-16 17:57:09 +01:00
if ( Utils . debugOn ) {
ex . printStackTrace ( ) ;
}
throw new Error ( Errors . SYNTAX_ERROR ) ;
}
2017-01-31 22:29:49 +01:00
} 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 " ) ;
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . error = e . id . toString ( ) ;
2017-01-16 17:57:09 +01:00
System . err . println ( e . id ) ;
}
2017-06-09 22:47:30 +02:00
* /
2017-01-16 17:57:09 +01:00
}
2017-04-10 22:50:43 +02:00
@SuppressWarnings ( " unused " )
@Deprecated
2016-11-02 21:56:40 +01:00
private void changeEquationScreen ( ) {
2017-05-16 22:02:44 +02:00
throw new UnsupportedOperationException ( ) ;
2017-04-10 22:50:43 +02:00
//
// if (!userInput.isEmpty()) {
// final MathInputScreen cloned = clone();
// cloned.userInput.setCaretPosition(cloned.userInput.getCaretMaxPosition()-1);
// DisplayManager.INSTANCE.replaceScreen(cloned);
// initialized = false;
// DisplayManager.INSTANCE.setScreen(this);
//
// }
2016-11-02 21:56:40 +01:00
}
2017-03-26 22:44:09 +02:00
public void typeChar ( char chr ) {
userInput . typeChar ( chr ) ;
mustRefresh = true ;
2016-09-02 20:32:37 +02:00
}
2017-04-10 22:50:43 +02:00
2016-09-02 20:32:37 +02:00
@Override
public boolean keyReleased ( Key k ) {
2017-05-05 22:27:11 +02:00
if ( k = = Key . OK ) {
return true ;
} else {
if ( userInput . isExtraOpened ( ) & & userInput . getExtraKeyboardEventListener ( ) . keyReleased ( k ) ) {
return true ;
} else {
switch ( k ) {
default :
return false ;
}
}
}
2016-09-02 20:32:37 +02:00
}
2017-01-31 22:29:49 +01:00
2017-01-17 22:32:40 +01:00
public void showVariablesDialog ( ) {
showVariablesDialog ( null ) ;
}
2017-01-31 22:29:49 +01:00
2017-01-16 17:57:09 +01:00
public void showVariablesDialog ( final Runnable runnable ) {
2017-01-31 22:29:49 +01:00
final Thread ct = new Thread ( ( ) - > {
2017-03-03 23:06:43 +01:00
final ObjectArrayList < Function > knownVarsInFunctions = getKnownVariables ( calc . f . toArray ( new Function [ calc . f . size ( ) ] ) ) ;
2017-01-31 22:29:49 +01:00
for ( final VariableValue f : calc . variablesValues ) {
2017-02-06 21:46:43 +01:00
if ( knownVarsInFunctions . contains ( f . v ) ) {
knownVarsInFunctions . remove ( f . v ) ;
2017-01-16 17:57:09 +01:00
}
}
2017-04-10 22:50:43 +02:00
2017-01-16 17:57:09 +01:00
boolean cancelled = false ;
2017-02-06 21:46:43 +01:00
for ( final Function f : knownVarsInFunctions ) {
2017-01-31 22:29:49 +01:00
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 {
2017-09-24 18:47:30 +02:00
DisplayManager . INSTANCE . screenChange . acquire ( ) ;
2017-01-31 22:29:49 +01:00
} 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
}
}
2017-01-31 22:29:49 +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-31 22:29:49 +01:00
2017-03-03 23:06:43 +01:00
private ObjectArrayList < Function > getKnownVariables ( Function [ ] fncs ) {
final ObjectArrayList < Function > res = new ObjectArrayList < > ( ) ;
2017-01-31 22:29:49 +01:00
for ( final Function f : fncs ) {
2017-02-14 20:02:03 +01:00
if ( f instanceof FunctionOperator ) {
res . addAll ( getKnownVariables ( new Function [ ] { ( ( FunctionOperator ) f ) . getParameter1 ( ) , ( ( FunctionOperator ) f ) . getParameter2 ( ) } ) ) ;
} else if ( f instanceof FunctionDynamic ) {
res . addAll ( getKnownVariables ( ( ( FunctionDynamic ) f ) . getParameters ( ) ) ) ;
} else if ( f instanceof FunctionSingle ) {
res . addAll ( getKnownVariables ( new Function [ ] { ( ( FunctionSingle ) f ) . getParameter ( ) } ) ) ;
2017-01-16 17:57:09 +01:00
} else if ( f instanceof Variable ) {
2017-07-24 23:11:29 +02:00
if ( ( ( Variable ) f ) . getType ( ) = = Variable . V_TYPE . CONSTANT ) {
2017-02-06 21:46:43 +01:00
if ( ! res . contains ( f ) ) {
res . add ( f ) ;
}
2017-01-16 17:57:09 +01:00
}
}
}
return res ;
}
2017-01-31 22:29:49 +01:00
2016-11-02 21:56:40 +01:00
@Override
2017-04-10 22:50:43 +02:00
@Deprecated
2016-12-04 22:22:16 +01:00
public MathInputScreen clone ( ) {
2017-05-16 22:02:44 +02:00
throw new UnsupportedOperationException ( ) ;
2017-04-10 22:50:43 +02:00
// final MathInputScreen es = this;
// final MathInputScreen es2 = new MathInputScreen();
// es2.errorLevel = es.errorLevel;
// es2.mustRefresh = es.mustRefresh;
// es2.calc = Utils.cloner.deepClone(es.calc);
// es2.userInput = Utils.cloner.deepClone(es.userInput);
// es2.result = Utils.cloner.deepClone(es.result);
// return es2;
2016-11-02 21:56:40 +01:00
}
2016-09-02 20:32:37 +02:00
}