2018-09-02 13:36:49 +02:00
package it.cavallium.warppi.gui.screens ;
2016-09-02 20:32:37 +02:00
2017-03-26 22:44:09 +02:00
import java.io.IOException ;
2018-10-04 12:38:54 +02:00
import java.util.HashMap ;
import org.apache.commons.lang3.SerializationUtils ;
2018-06-09 19:37:34 +02:00
2018-09-04 12:12:41 +02:00
import it.cavallium.warppi.Engine ;
2018-09-12 22:16:33 +02:00
import it.cavallium.warppi.Platform.ConsoleUtils ;
2018-09-02 13:36:49 +02:00
import it.cavallium.warppi.device.Keyboard ;
import it.cavallium.warppi.event.Key ;
import it.cavallium.warppi.event.KeyPressedEvent ;
import it.cavallium.warppi.event.KeyReleasedEvent ;
import it.cavallium.warppi.gui.expression.InputContext ;
import it.cavallium.warppi.gui.expression.blocks.Block ;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer ;
import it.cavallium.warppi.gui.expression.containers.InputContainer ;
import it.cavallium.warppi.gui.expression.containers.NormalInputContainer ;
import it.cavallium.warppi.gui.expression.containers.NormalOutputContainer ;
import it.cavallium.warppi.gui.expression.containers.OutputContainer ;
import it.cavallium.warppi.gui.graphicengine.BinaryFont ;
import it.cavallium.warppi.gui.graphicengine.Renderer ;
import it.cavallium.warppi.math.AngleMode ;
import it.cavallium.warppi.math.Function ;
import it.cavallium.warppi.math.FunctionDynamic ;
import it.cavallium.warppi.math.FunctionOperator ;
import it.cavallium.warppi.math.FunctionSingle ;
import it.cavallium.warppi.math.MathContext ;
import it.cavallium.warppi.math.MathematicalSymbols ;
import it.cavallium.warppi.math.functions.Expression ;
import it.cavallium.warppi.math.functions.Number ;
import it.cavallium.warppi.math.functions.Variable ;
2018-10-04 12:38:54 +02:00
import it.cavallium.warppi.math.functions.Variable.V_TYPE ;
2018-09-02 13:36:49 +02:00
import it.cavallium.warppi.math.functions.Variable.VariableValue ;
import it.cavallium.warppi.math.parser.MathParser ;
import it.cavallium.warppi.math.solver.MathSolver ;
2018-09-12 22:16:33 +02:00
import it.cavallium.warppi.util.Error ;
import it.cavallium.warppi.util.Errors ;
import it.cavallium.warppi.util.Utils ;
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 ) ;
2018-05-12 21:18:29 +02:00
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 ;
2018-09-02 12:45:51 +02:00
@SuppressWarnings ( " unused " )
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 {
2018-09-11 19:19:24 +02:00
BlockContainer . initializeFonts ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . loadFont ( " norm " ) , Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ( ) ;
2018-09-04 12:12:41 +02:00
Engine . getPlatform ( ) . exit ( 1 ) ;
2017-03-26 22:44:09 +02:00
}
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
2018-03-17 00:09:40 +01:00
public void initialized ( ) 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
2018-09-22 11:17:30 +02:00
public void beforeRender ( final float dt ) {
2018-09-28 11:39:28 +02:00
if ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . error = = null ) {
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . renderer . glClearColor ( 0xFFc5c2af ) ;
2018-09-28 11:39:28 +02:00
} else {
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . renderer . glClearColor ( 0xFFDC3C32 ) ;
2018-09-28 11:39:28 +02:00
}
if ( userInput . beforeRender ( dt ) ) {
2017-03-26 22:44:09 +02:00
mustRefresh = true ;
2018-09-28 11:39:28 +02:00
}
2017-11-19 12:55:48 +01:00
if ( computingResult ) {
computingElapsedTime + = dt ;
2018-05-12 21:18:29 +02:00
computingAnimationElapsedTime + = dt ;
2017-11-19 12:55:48 +01:00
if ( computingAnimationElapsedTime > 0 . 1 ) {
computingAnimationElapsedTime - = 0 . 1 ;
computingAnimationIndex = ( computingAnimationIndex + 1 ) % 16 ;
mustRefresh = true ;
}
2018-09-28 11:39:28 +02:00
if ( computingElapsedTime > 5 ) {
2017-11-19 12:55:48 +01:00
computingBreakTipVisible = true ;
2018-09-28 11:39:28 +02:00
}
2017-11-19 12:55:48 +01:00
} else {
computingElapsedTime = 0 ;
computingAnimationElapsedTime = 0 ;
computingAnimationIndex = 0 ;
computingBreakTipVisible = false ;
}
2016-09-02 20:32:37 +02:00
}
2018-05-12 21:18:29 +02:00
2017-11-19 12:55:48 +01:00
@Override
public void render ( ) {
2018-09-11 19:19:24 +02:00
final Renderer renderer = Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . renderer ;
2018-09-22 11:17:30 +02:00
MathInputScreen . fontBig . use ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine ) ;
2017-11-19 12:55:48 +01:00
final int textColor = 0xFF000000 ;
final int padding = 4 ;
renderer . glColor ( textColor ) ;
2016-09-02 20:32:37 +02:00
2018-09-11 19:19:24 +02:00
userInput . draw ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine , renderer , padding , padding + 20 ) ;
2017-11-19 12:55:48 +01:00
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 ;
2018-09-11 19:19:24 +02:00
renderer . glFillRect ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . getWidth ( ) - size - 4 , Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . getHeight ( ) - size - 4 , size , size , leftX + size * posX , leftY + size * posY , size , size ) ;
2017-11-19 12:55:48 +01:00
if ( computingBreakTipVisible ) {
2018-09-11 19:19:24 +02:00
Utils . getFont ( false ) . use ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine ) ;
2017-11-19 12:55:48 +01:00
renderer . glColor3f ( 0 . 75f , 0 , 0 ) ;
2018-09-11 19:19:24 +02:00
renderer . glDrawStringRight ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . getWidth ( ) - 4 - size - 4 , Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . getHeight ( ) - size / 2 - renderer . getCurrentFont ( ) . getCharacterHeight ( ) / 2 - 4 , " Press (=) to stop " ) ;
2017-11-19 12:55:48 +01:00
}
2018-09-28 11:39:28 +02:00
} else if ( ! result . isContentEmpty ( ) ) {
2018-09-22 11:17:30 +02:00
result . draw ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine , renderer , Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . getWidth ( ) - result . getWidth ( ) - 2 , Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine . getHeight ( ) - result . getHeight ( ) - 2 ) ;
2018-09-28 11:39:28 +02:00
}
2017-11-19 12:55:48 +01:00
}
2017-01-31 22:29:49 +01:00
2017-01-22 13:46:38 +01:00
@Override
2018-03-17 00:09:40 +01:00
public void renderTopmost ( ) {
2018-09-11 19:19:24 +02:00
final Renderer renderer = Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ;
2018-09-28 11:39:28 +02:00
if ( calc . exactMode ) {
2017-01-22 13:46:38 +01:00
skinN = 22 ;
2018-09-28 11:39:28 +02:00
} else {
2017-01-22 13:46:38 +01:00
skinN = 21 ;
2018-09-28 11:39:28 +02:00
}
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . guiSkin . use ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . engine ) ;
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 ;
2018-09-28 11:39:28 +02:00
} else {
2016-09-02 20:32:37 +02:00
return false ;
2018-09-28 11:39:28 +02:00
}
2016-09-02 20:32:37 +02:00
}
@Override
2018-09-22 11:17:30 +02:00
public boolean onKeyPressed ( final KeyPressedEvent k ) {
2018-09-11 01:12:54 +02:00
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( ConsoleUtils . OUTPUTLEVEL_DEBUG_MIN , " MathInputScreen " , " Pressed key " + k . getKey ( ) . toString ( ) ) ;
2018-03-11 21:49:41 +01:00
try {
2018-06-30 18:46:53 +02:00
switch ( k . getKey ( ) ) {
2018-03-11 21:49:41 +01:00
case OK :
userInput . toggleExtra ( ) ;
2017-05-05 22:27:11 +02:00
mustRefresh = true ;
2017-01-16 17:57:09 +01:00
return true ;
2018-03-11 21:49:41 +01:00
case HISTORY_BACK :
if ( userInput . isExtraOpened ( ) ) {
userInput . closeExtra ( ) ;
currentStep = 0 ;
mustRefresh = true ;
return true ;
}
2018-09-22 10:29:40 +02:00
case BACK :
if ( userInput . isExtraOpened ( ) ) {
userInput . closeExtra ( ) ;
mustRefresh = true ;
return true ;
}
2018-03-11 21:49:41 +01:00
default :
2018-06-30 18:46:53 +02:00
if ( userInput . isExtraOpened ( ) & & userInput . getExtraKeyboardEventListener ( ) . onKeyPressed ( k ) ) {
2018-03-11 21:49:41 +01:00
currentStep = 0 ;
return true ;
} else {
2018-06-30 18:46:53 +02:00
final boolean step = k . getKey ( ) = = Key . STEP ;
switch ( k . getKey ( ) ) {
2017-05-05 22:27:11 +02:00
2018-03-11 21:49:41 +01:00
case STEP :
currentStep + + ;
case SIMPLIFY :
2018-09-28 11:39:28 +02:00
if ( ! step ) {
2018-05-12 21:18:29 +02:00
currentStep = 0 ;
2018-09-28 11:39:28 +02:00
}
2018-09-11 19:19:24 +02:00
if ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . error ! = null ) {
2018-03-11 21:49:41 +01:00
//TODO: make the error management a global API rather than being relegated to this screen.
2018-09-04 12:12:41 +02:00
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( 1 , " Resetting after error... " ) ;
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . error = null ;
2018-03-11 21:49:41 +01:00
calc . f = null ;
calc . f2 = null ;
calc . resultsCount = 0 ;
return true ;
2018-09-22 11:17:30 +02:00
} else if ( ! computingResult ) {
computingResult = true ;
computingThread = new Thread ( ( ) - > {
try {
2017-11-19 12:55:48 +01:00
try {
2018-09-22 11:17:30 +02:00
if ( ! userInput . isAlreadyParsed ( ) & & ! userInput . isEmpty ( ) ) {
final 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 ( ) ;
2017-11-19 12:55:48 +01:00
}
2018-09-22 11:17:30 +02:00
calc . f . add ( expr ) ;
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( 2 , " INPUT: " + expr ) ;
final MathSolver ms = new MathSolver ( expr ) ;
final ObjectArrayList < ObjectArrayList < Function > > resultSteps = ms . solveAllSteps ( ) ;
resultSteps . add ( 0 , Utils . newArrayList ( expr ) ) ;
final ObjectArrayList < Function > resultExpressions = resultSteps . get ( resultSteps . size ( ) - 1 ) ;
2018-09-28 11:39:28 +02:00
for ( final Function rr : resultExpressions ) {
2018-09-22 11:17:30 +02:00
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( 0 , " RESULT: " + rr . toString ( ) ) ;
2018-09-28 11:39:28 +02:00
}
2018-09-22 11:17:30 +02:00
final ObjectArrayList < ObjectArrayList < Block > > resultBlocks = MathParser . parseOutput ( calc , resultExpressions ) ;
result . setContentAsMultipleGroups ( resultBlocks ) ;
// showVariablesDialog(() -> {
// currentExpression = newExpression;
// simplify();
// });
2018-10-04 12:38:54 +02:00
this . swapInputScreen ( ) ;
2017-06-05 22:50:33 +02:00
}
2018-09-22 11:17:30 +02:00
} catch ( final InterruptedException ex ) {
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( ConsoleUtils . OUTPUTLEVEL_DEBUG_MIN , " Computing thread stopped. " ) ;
} catch ( final Exception ex ) {
2018-09-28 11:39:28 +02:00
if ( Engine . getPlatform ( ) . getSettings ( ) . isDebugEnabled ( ) ) {
2018-09-22 11:17:30 +02:00
ex . printStackTrace ( ) ;
2018-09-28 11:39:28 +02:00
}
2018-09-22 11:17:30 +02:00
throw new Error ( Errors . SYNTAX_ERROR ) ;
2017-06-09 22:47:30 +02:00
}
2018-09-22 11:17:30 +02:00
} catch ( final Error e ) {
d . errorStackTrace = Engine . getPlatform ( ) . stacktraceToString ( e ) ;
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . error = e . id . toString ( ) ;
System . err . println ( e . id ) ;
2018-03-11 21:49:41 +01:00
}
2018-09-22 11:17:30 +02:00
computingResult = false ;
} ) ;
Engine . getPlatform ( ) . setThreadName ( computingThread , " Computing Thread " ) ;
Engine . getPlatform ( ) . setThreadDaemon ( computingThread ) ;
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
}
2018-09-22 11:17:30 +02:00
return false ;
2017-05-05 22:27:11 +02:00
}
2018-03-11 21:49:41 +01: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 ;
2018-05-06 16:37:25 +02:00
case EULER_NUMBER :
typeChar ( MathematicalSymbols . EULER_NUMBER ) ;
return true ;
2018-03-11 21:49:41 +01:00
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 ;
2018-05-05 23:06:36 +02:00
case LOGARITHM :
typeChar ( MathematicalSymbols . LOGARITHM ) ;
return true ;
2018-03-11 21:49:41 +01:00
case DELETE :
userInput . del ( ) ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2018-03-11 21:49:41 +01:00
mustRefresh = true ;
return true ;
case LEFT :
userInput . moveLeft ( ) ;
mustRefresh = true ;
return true ;
case RIGHT :
userInput . moveRight ( ) ;
mustRefresh = true ;
2017-05-05 22:27:11 +02:00
return true ;
2018-03-11 21:49:41 +01:00
case RESET :
userInput . clear ( ) ;
result . clear ( ) ;
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2018-09-11 19:19:24 +02:00
if ( Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . error ! = null ) {
2018-09-04 12:12:41 +02:00
Engine . getPlatform ( ) . getConsoleUtils ( ) . out ( ) . println ( 1 , " Resetting after error... " ) ;
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . error = null ;
2018-03-11 21:49:41 +01:00
}
return true ;
case SURD_MODE :
calc . exactMode = ! calc . exactMode ;
2018-09-11 19:36:02 +02:00
if ( ! result . isContentEmpty ( ) ) {
result . clear ( ) ;
currentStep = 0 ;
Keyboard . keyPressed ( Key . SIMPLIFY ) ;
}
2018-03-11 21:49:41 +01:00
return true ;
case debug1 :
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . setScreen ( new EmptyScreen ( ) ) ;
2017-05-05 22:27:11 +02:00
return true ;
2018-03-11 21:49:41 +01:00
case HISTORY_BACK :
2018-09-11 19:19:24 +02:00
// if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().canGoBack()) {
// if (currentExpression != null && currentExpression.length() > 0 & Engine.INSTANCE.getHardwareDevice().getDisplayManager().sessions[Engine.INSTANCE.getHardwareDevice().getDisplayManager().currentSession + 1] instanceof MathInputScreen) {
2018-03-11 21:49:41 +01:00
// newExpression = currentExpression;
// try {
// interpreta(true);
// } catch (final Error e) {}
// }
// }
return false ;
case HISTORY_FORWARD :
2018-09-11 19:19:24 +02:00
// if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().canGoForward()) {
// if (currentExpression != null && currentExpression.length() > 0 & Engine.INSTANCE.getHardwareDevice().getDisplayManager().sessions[Engine.INSTANCE.getHardwareDevice().getDisplayManager().currentSession - 1] instanceof MathInputScreen) {
2018-03-11 21:49:41 +01:00
// newExpression = currentExpression;
// try {
// interpreta(true);
// } catch (final Error e) {}
// }
// }
return false ;
case debug_DEG :
if ( calc . angleMode . equals ( AngleMode . DEG ) = = false ) {
calc . angleMode = AngleMode . DEG ;
currentStep = 0 ;
return true ;
}
return false ;
case debug_RAD :
if ( calc . angleMode . equals ( AngleMode . RAD ) = = false ) {
calc . angleMode = AngleMode . RAD ;
currentStep = 0 ;
return true ;
}
return false ;
case debug_GRA :
if ( calc . angleMode . equals ( AngleMode . GRA ) = = false ) {
calc . angleMode = AngleMode . GRA ;
currentStep = 0 ;
return true ;
}
return false ;
case DRG_CYCLE :
2018-09-28 11:39:28 +02:00
if ( calc . angleMode . equals ( AngleMode . DEG ) = = true ) {
2018-03-11 21:49:41 +01:00
calc . angleMode = AngleMode . RAD ;
2018-09-28 11:39:28 +02:00
} else if ( calc . angleMode . equals ( AngleMode . RAD ) = = true ) {
2018-03-11 21:49:41 +01:00
calc . angleMode = AngleMode . GRA ;
2018-09-28 11:39:28 +02:00
} else {
2018-03-11 21:49:41 +01:00
calc . angleMode = AngleMode . DEG ;
2018-09-28 11:39:28 +02:00
}
2017-12-20 18:07:11 +01:00
currentStep = 0 ;
2017-05-05 22:27:11 +02:00
return true ;
2018-03-11 21:49:41 +01:00
default :
return false ;
}
2017-05-05 22:27:11 +02:00
}
2018-03-11 21:49:41 +01:00
}
2018-05-12 21:18:29 +02:00
} catch ( final Exception ex ) {
2018-03-11 21:49:41 +01:00
ex . printStackTrace ( ) ;
return true ;
2016-09-02 20:32:37 +02:00
}
}
2017-01-31 22:29:49 +01:00
2018-10-04 12:38:54 +02:00
@SuppressWarnings ( " unchecked " )
private void swapInputScreen ( ) {
MathInputScreen mis = new MathInputScreen ( ) ;
mis . calc = SerializationUtils . clone ( calc ) ;
mis . canBeInHistory = true ;
mis . currentStep = currentStep ;
mis . created = created ;
mis . d = d ;
mis . errorLevel = errorLevel ;
mis . ic = SerializationUtils . clone ( ic ) ;
mis . initialized = initialized ;
mis . mustRefresh = true ;
mis . result = SerializationUtils . clone ( result ) ;
mis . userInput = SerializationUtils . clone ( userInput ) ;
mis . d = d ;
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . setScreen ( mis ) ;
}
2017-06-09 22:47:30 +02:00
@SuppressWarnings ( " unused " )
@Deprecated
2018-09-22 11:17:30 +02:00
private ObjectArrayList < Function > solveExpression ( final 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 " ) ;
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ) {
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ( ) ;
}
}
2018-09-28 11:39:28 +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 " ) ;
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ) {
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . setScreen ( new SolveEquationScreen ( this ) ) ;
2017-01-16 17:57:09 +01:00
return ;
}
}
2018-09-28 11:39:28 +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 " ) ;
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ( ) ;
2018-09-22 11:17:30 +02:00
//
2017-04-10 22:50:43 +02:00
// if (!userInput.isEmpty()) {
// final MathInputScreen cloned = clone();
// cloned.userInput.setCaretPosition(cloned.userInput.getCaretMaxPosition()-1);
2018-09-11 19:19:24 +02:00
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().replaceScreen(cloned);
2017-04-10 22:50:43 +02:00
// initialized = false;
2018-09-11 19:19:24 +02:00
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().setScreen(this);
2017-04-10 22:50:43 +02:00
//
// }
2016-11-02 21:56:40 +01:00
}
2018-09-22 11:17:30 +02:00
public void typeChar ( final char chr ) {
2017-03-26 22:44:09 +02:00
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
2018-09-22 11:17:30 +02:00
public boolean onKeyReleased ( final KeyReleasedEvent k ) {
2018-09-28 11:39:28 +02:00
if ( k . getKey ( ) = = Key . OK ) {
2017-05-05 22:27:11 +02:00
return true ;
2018-09-28 11:39:28 +02:00
} else if ( userInput . isExtraOpened ( ) & & userInput . getExtraKeyboardEventListener ( ) . onKeyReleased ( k ) ) {
2018-09-22 11:17:30 +02:00
return true ;
2018-09-28 11:39:28 +02:00
} else {
2018-09-22 11:17:30 +02:00
switch ( k . getKey ( ) ) {
default :
return false ;
2017-05-05 22:27:11 +02:00
}
2018-09-28 11:39:28 +02:00
}
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 ( ) ] ) ) ;
2018-09-28 11:39:28 +02:00
for ( final VariableValue f : calc . variablesValues ) {
if ( knownVarsInFunctions . contains ( f . v ) ) {
2017-02-06 21:46:43 +01:00
knownVarsInFunctions . remove ( f . v ) ;
2018-09-28 11:39:28 +02: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 ) ) ) ;
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . setScreen ( cvs ) ;
2017-01-16 17:57:09 +01:00
try {
2018-09-11 19:19:24 +02:00
Engine . INSTANCE . getHardwareDevice ( ) . getDisplayManager ( ) . 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 ( ) ;
2018-09-28 11:39:28 +02:00
for ( int i = 0 ; i < is ; i + + ) {
if ( calc . variablesValues . get ( i ) . v = = f ) {
2017-01-17 22:32:40 +01:00
calc . variablesValues . remove ( i ) ;
2018-09-28 11:39:28 +02: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
}
}
2018-09-28 11:39:28 +02:00
if ( ! cancelled ) {
if ( runnable ! = null ) {
2017-01-17 22:32:40 +01:00
runnable . run ( ) ;
2018-09-28 11:39:28 +02:00
}
}
2017-01-16 17:57:09 +01:00
} ) ;
2018-09-04 12:12:41 +02:00
Engine . getPlatform ( ) . setThreadName ( ct , " Variables user-input queue thread " ) ;
2017-01-16 17:57:09 +01:00
ct . setPriority ( Thread . MIN_PRIORITY ) ;
2018-09-04 12:12:41 +02:00
Engine . getPlatform ( ) . setThreadDaemon ( ct ) ;
2017-01-16 17:57:09 +01:00
ct . start ( ) ;
}
2017-01-31 22:29:49 +01:00
2018-09-22 11:17:30 +02:00
private ObjectArrayList < Function > getKnownVariables ( final Function [ ] fncs ) {
2017-03-03 23:06:43 +01:00
final ObjectArrayList < Function > res = new ObjectArrayList < > ( ) ;
2018-09-28 11:39:28 +02:00
for ( final Function f : fncs ) {
if ( f instanceof FunctionOperator ) {
2017-02-14 20:02:03 +01:00
res . addAll ( getKnownVariables ( new Function [ ] { ( ( FunctionOperator ) f ) . getParameter1 ( ) , ( ( FunctionOperator ) f ) . getParameter2 ( ) } ) ) ;
2018-09-28 11:39:28 +02:00
} else if ( f instanceof FunctionDynamic ) {
2017-02-14 20:02:03 +01:00
res . addAll ( getKnownVariables ( ( ( FunctionDynamic ) f ) . getParameters ( ) ) ) ;
2018-09-28 11:39:28 +02:00
} else if ( f instanceof FunctionSingle ) {
2017-02-14 20:02:03 +01:00
res . addAll ( getKnownVariables ( new Function [ ] { ( ( FunctionSingle ) f ) . getParameter ( ) } ) ) ;
2018-09-28 11:39:28 +02:00
} else if ( f instanceof Variable ) {
if ( ( ( Variable ) f ) . getType ( ) = = Variable . V_TYPE . CONSTANT ) {
if ( ! res . contains ( f ) ) {
2017-02-06 21:46:43 +01:00
res . add ( f ) ;
2018-09-28 11:39:28 +02:00
}
}
}
}
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
2018-10-04 12:38:54 +02:00
public String getSessionTitle ( ) {
return " Calculator " ;
2016-11-02 21:56:40 +01:00
}
2016-09-02 20:32:37 +02:00
}