extern "C" { #include #include #include #include } #include #include "../poincare/src/layout/string_layout.h" #include "plot.h" #include "utils.h" static const char* kParsingErrorMessage = "PARSING ERROR"; ////////////////////////////////////////////////////// static constexpr uint8_t kInputMemory = 15; typedef struct user_expression_t { char* text_input; Expression* expression; Expression* simplified; ExpressionLayout* expression_layout; ExpressionLayout* simplified_layout; } user_expression_t; class UserExpressions { public: UserExpressions() { m_numberOfExpressions = 0; m_position = kInputMemory; for (int i=0; icreateLayout(); user_expression.simplified = user_expression.expression->simplify(); user_expression.simplified_layout = user_expression.simplified->createLayout(); } else { user_expression.expression_layout = new StringLayout(kParsingErrorMessage, strlen(kParsingErrorMessage)); } return user_expression; } static int16_t print_user_input(user_expression_t user_expression, int16_t yOffset) { if (user_expression.expression_layout) { int16_t height = user_expression.expression_layout->size().height; if (yOffset + height < ION_SCREEN_HEIGHT) { user_expression.expression_layout->draw(KDPointMake(0, yOffset)); } yOffset += height; } if (user_expression.simplified_layout) { int16_t height = user_expression.simplified_layout->size().height; if (yOffset + height < ION_SCREEN_HEIGHT) { int16_t xOffset = ION_SCREEN_WIDTH - user_expression.simplified_layout->size().width; user_expression.simplified_layout->draw(KDPointMake(xOffset, yOffset)); } yOffset += height; } return yOffset; } static void print_user_inputs(const UserExpressions& user_inputs, uint8_t startingAt) { int16_t yOffset = 0; for (uint8_t i=startingAt; iION_SCREEN_HEIGHT) { break; } } } static void interactive_expression_parsing() { UserExpressions user_inputs = UserExpressions(); int index = 0; while (1) { text_event_t text_event; if (index == 0) { text_event = get_text(nullptr); } else { text_event = get_text(user_inputs.get_expression(index - 1).text_input); } if (text_event.event == EQUAL) { user_inputs.append_expression(create_user_input(text_event.text)); } else if (text_event.event == UP_ARROW) { index--; if (index < 0) { index = 0; } } else if (text_event.event == DOWN_ARROW) { if (user_inputs.numberOfExpressions() != 0) { index++; if (index >= user_inputs.numberOfExpressions()) { index = user_inputs.numberOfExpressions() - 1; } } } else if (text_event.event == PLOT) { user_inputs.append_expression(create_user_input(text_event.text)); // We check that the expression is correct. if (user_inputs.get_expression(0).expression) { clear_screen(); plot(user_inputs.get_expression(0).expression, -3, 3); } } else { assert(false); // unreachable. } clear_screen(); print_user_inputs(user_inputs, index ? index - 1 : 0); } } void ion_app() { interactive_expression_parsing(); while (1) { ion_sleep(); } }