#include <Adafruit_ILI9341.h>
#include <Adafruit_FT6206.h>
#include "Fonts/FreeSerif9pt7b.h"
#include "Fonts/FreeSerif12pt7b.h"
Adafruit_ILI9341 tft(10,9);
Adafruit_FT6206 ts;
void Text1(int x, int y, int size, int color, String msg) {
tft.setFont(&FreeSerif12pt7b);
tft.setCursor(x,y);
tft.setTextSize(size);
tft.setTextColor(color);
tft.print(msg);
}
void Text(int x, int y, int size, int color, String msg) {
tft.setFont(&FreeSerif9pt7b);
tft.setCursor(x,y);
tft.setTextSize(size);
tft.setTextColor(color);
tft.print(msg);
}
void printVal(int x, int y, int size, int color, double num) {
tft.setFont(&FreeSerif9pt7b);
tft.setCursor(x,y);
tft.setTextSize(size);
tft.setTextColor(color);
tft.print(num);
}
int calcDecimal(String str) {
int dec = 5;
for(int i=str.length()-1; str[i] != '.'; i--) {
if(str[i] == '0') dec--;
else return dec;
}
return dec;
}
void createCalcInterface() {
String label[] = {"AC", " ", "+/-", "/", "7", "8", "9", "x", "4", "5", "6", "-", "1", "2", "3", "+", "%", "0", ".", "="};
for(int i=0; i<20; i++) {
if(i/4 == 0 || i%4 == 3) {
tft.fillRoundRect(10+(i%4)*60, 90+(i/4)*45, 40, 35, 15, 0xef7f);
Text(20+(i%4)*60, 120+(i/4)*45, 1, 0x001f, label[i]);
} else {
tft.fillRoundRect(10+(i%4)*60, 90+(i/4)*45, 40, 35, 15, 0xf7be); //ef7d
Text(25+(i%4)*60, 115+(i/4)*45, 1, 0x0, label[i]);
}
}
}
void calculate() {
bool run = true, started = false;
float n = 0;
float n1 = 0, n2 = 0;
int decimal = 0;
bool point = false;
bool operatorDefined = false;
bool calculated = false;
char operation = '+';
int userCursor = 0, ansCursor = 0;
String userDisplay = "";
String ansDisplay = "";
while(run) {
bool reading = true;
while(reading) {
if(!ts.touched()) continue;
int select_x = (Touch_x()-10)/60;
int select_y = (Touch_y()-90)/45;
if(select_x > 2 || select_y < 1 || (select_x == 0 && select_y == 4)) {
if(select_x > 2) {
if(select_y == 4) {
if(calculated) {
delay(200); continue;
}
Text1(220-userCursor, 25, 1, 0xffff, userDisplay);
Text(220-ansCursor, 75, 1, 0xffff, ansDisplay);
userDisplay = ansDisplay; ansDisplay = "";
userCursor = 12*(userDisplay.length()-1);
Text1(220-userCursor, 25, 1, 0xf, userDisplay);
calculated = true;
delay(200);
continue;
}
switch(select_y) {
case 0: operation = '/'; break;
case 1: operation = '*'; break;
case 2: operation = '-'; break;
case 3: operation = '+'; break;
}
Text1(220-userCursor, 25, 1, 0xffff, userDisplay);
if(operatorDefined) {
userDisplay.remove(userDisplay.length()-1);
userCursor -= 12;
}
operatorDefined = true;
userDisplay += operation;
if(userCursor <200 || userDisplay.length() >= 34) userCursor += 12;
Text1(220-userCursor, 25, 1, 0xf, userDisplay);
started = true; n=0; n2 = n1; point = false; decimal = 0;
delay(200);
}
else if(select_x == 0 && select_y == 0) {
Text(220-ansCursor, 75, 1, 0xffff, ansDisplay);//String(n1,calcDecimal(String(n1,5))));
Text1(220-userCursor, 25, 1, 0xffff, userDisplay);
userCursor = 0; ansCursor = 0; n1 = 0; n2 = 0; n = 0; userDisplay = ""; ansDisplay = "";
started = false; operatorDefined = false; point = false; calculated = false; decimal = 0;
delay(200);
}
} else {
int enteredDigit;
if(select_y < 4) {
enteredDigit = 3*(3-select_y)+select_x+1;
} else {
if(select_x == 1) enteredDigit = 0;
else if(select_x == 2) {
if(point) continue;
point = true; operatorDefined = false;
Text1(220-userCursor, 25, 1, 0xffff, userDisplay);
userDisplay += "."; if(userCursor <200 || userDisplay.length() >= 34) userCursor += 4;
Text1(220-userCursor, 25, 1, 0xf, userDisplay);
delay(200);
continue;
}
}
if(calculated && operatorDefined) calculated = false;
operatorDefined = false;
if(point) {
decimal++;
n = n + float(enteredDigit)/(pow(10.00000,decimal));
} else n = 10*n + enteredDigit;
Text1(220-userCursor, 25, 1, 0xffff, userDisplay);
userDisplay += String(enteredDigit);
if(userCursor < 200 || userDisplay.length() >= 34) userCursor += 12;
Text1(220-userCursor, 25, 1, 0xf, userDisplay);
if(!started) {
Text(220-ansCursor, 75, 1, 0xffff, ansDisplay);//String(n1,calcDecimal(String(n1,calcDecimal(String(n1,5))))));
n1 = n; ansDisplay = String(n1,calcDecimal(String(n1,5)));
ansCursor = 10*(ansDisplay.length()-1);
Text(220-ansCursor, 75, 1, 0x8410, ansDisplay);//String(n1,calcDecimal(String(n1,5))));
} else {
Text(220-ansCursor, 75, 1, 0xffff, ansDisplay);//String(n1,calcDecimal(String(n1,5))));
n1 = n2;
switch(operation) {
case '/': n1/=n; break;
case '*': n1*=n; break;
case '+': n1+=n; break;
case '-': n1-=n; break;
}
ansDisplay = String(n1,calcDecimal(String(n1,5)));
ansCursor = 10*(ansDisplay.length()-1);
Text(220-ansCursor, 75, 1, 0x8410, ansDisplay);//String(n1,calcDecimal(String(n1,5))));
}
delay(200);
}
}
}
}
int checkPriority(char oper) {
if(oper == '/') return 1;
else if(oper == '*') return 2;
else if(oper == '+') return 3;
else if(oper == '-') return 4;
return 5;
}
int compute(String userDisplay) {
String input = userDisplay;
int result = 0;
while(1) {
Serial.print("input : ");
Serial.println(input);
char oper = '+';
int operatorIdx = 0;
int priority = 200;
int start = 0, ending = 0;
int leftOperand = 0, rightOperand = 0;
for(int i=0; i<input.length(); i++) {
if(!isDigit(input[i])) {
if(checkPriority(input[i]) <= priority) {
priority = checkPriority(input[i]);
oper = input[i];
operatorIdx = i;
}
}
}
if(priority == 200 || operatorIdx == 0) {
result = input.toInt();
return result;
}
Serial.print("operator index : ");
Serial.println(operatorIdx);
int coeff = 1;
for(int i = operatorIdx-1; i>=0; i--) {
if(input[i] == '-') {
leftOperand *= (-1);
start = i;
break;
}
if(!isDigit(input[i])) {
start = i+1;
break;
}
leftOperand = leftOperand + coeff * (int(input[i]) - int('0'));
coeff *= 10;
}
for(int i = operatorIdx+1; i<input.length(); i++) {
if(!isDigit(input[i])) {
ending = i-1;
break;
}
rightOperand = 10*rightOperand + (int(input[i])-int('0'));
ending = i;
}
Serial.print("Left operand : ");
Serial.println(leftOperand);
Serial.print("Right operand : ");
Serial.println(rightOperand);
switch(oper) {
case '/' : result = leftOperand / rightOperand; break;
case '*' : result = leftOperand * rightOperand; break;
case '-' : result = leftOperand - rightOperand; break;
case '+' : result = leftOperand + rightOperand; break;
}
Serial.print("input at before edit : ");
Serial.println(input);
if(input[start] == '-') {
if(result < 0) {
input = input.substring(0, start) + String(result) + input.substring(ending+1);
} else input = input.substring(0, start) + "+" + String(result) + input.substring(ending+1);
} else input = input.substring(0, start) + String(result) + input.substring(ending+1);
Serial.print("input at last : ");
Serial.println(input);
result = 0;
}
}
void takeInput() {
bool run = true;
String userDisplay = "";
bool operatorDefined = false;
while(run) {
if(!ts.touched()) continue;
int select_x = (Touch_x()-10)/60;
int select_y = (Touch_y()-90)/45;
if(select_x > 2 && select_y < 4) {
Text1(220-(12*userDisplay.length()), 25, 1, 0xffff, userDisplay);
if(operatorDefined) {
userDisplay.remove(userDisplay.length() - 1, 1);
}
operatorDefined = true;
switch(select_y) {
case 0 : userDisplay += '/'; break;
case 1 : userDisplay += '*'; break;
case 2 : userDisplay += '-'; break;
case 3 : userDisplay += '+'; break;
}
} else if(select_y == 0 && select_x < 3) {
} else if(select_x < 3 && select_y > 0 && select_y < 4) {
operatorDefined = false;
Text1(220-(12*userDisplay.length()), 25, 1, 0xffff, userDisplay);
userDisplay += String((3-select_y)*3 + select_x + 1);
} else if(select_y == 4) {
operatorDefined = false;
if(select_x == 1) {
userDisplay += '0';
}
}
Text1(220-(12*userDisplay.length()), 25, 1, 0xf, userDisplay);
String calculation = userDisplay;
if(userDisplay[0] == '-') {
calculation = "0" + userDisplay;
}
if(!operatorDefined)
Serial.println(compute(calculation));
delay(200);
}
}
int Touch_x() {
TS_Point point = ts.getPoint();
return 240-point.x;
}
int Touch_y() {
TS_Point point = ts.getPoint();
return 320-point.y;
}
int currentState = 1;
int subState = 0;
int32_t num1 = 0, num2 = 0;
int currentNum = 1;
bool operationDefined = false;
void setup() {
tft.begin();
ts.begin();
tft.fillScreen(0xffff);
Serial.begin(115200);
float numb = 9.7000000;
Serial.println(String(numb,7));
//Serial.println(((Touch_x()-10)%60)+4*((Touch_y()-90)%45));
}
void loop() {
if(currentState == 1) {
if(subState == 0) {
createCalcInterface();
subState = 1;
}
if(ts.touched()) {
takeInput();
//calculate();
}
}
}