pebblisp/src/calc.c

145 lines
4.2 KiB
C
Raw Normal View History

2016-04-18 04:25:36 -04:00
#include <stdio.h>
#include <limits.h>
2020-05-04 18:14:41 -04:00
//#include "fixed.h"
2016-04-18 04:25:36 -04:00
#include "calc.h"
2020-05-04 18:14:41 -04:00
static inline int8_t tokenCount() {
return sizeof(tokens) / sizeof(tokens[0]);
2016-04-18 04:25:36 -04:00
}
2020-05-04 18:14:41 -04:00
static inline char* getToken(int8_t n) {
return tokens[n % tokenCount()];
}
// Currently selected button, starts on '('
static int8_t selected_token = 1;
2016-04-18 04:25:36 -04:00
2020-05-04 18:14:41 -04:00
// Update the current code text with the contents of `mytext`,
// and add the current selected_token to the end
2016-04-18 04:25:36 -04:00
static void updateText()
{
strcpy(temptext, mytext);
2020-05-03 17:00:45 -04:00
2020-05-04 18:14:41 -04:00
const char *token = getToken(selected_token);
if(token[0] == ' ') {
2016-04-18 04:25:36 -04:00
strcat(temptext, "_");
2020-05-04 18:14:41 -04:00
} else if(token[0] == '\n') {
strcat(temptext, "\\n");
2016-04-18 04:25:36 -04:00
} else {
2020-05-04 18:14:41 -04:00
strcat(temptext, token);
2016-04-18 04:25:36 -04:00
}
text_layer_set_text(s_input_text_layer, temptext);
}
2020-05-03 17:00:45 -04:00
// Button handler
2016-04-18 04:25:36 -04:00
static void up_down_handler(ClickRecognizerRef recognizer, void *context){
2020-05-04 18:14:41 -04:00
// Change current token
if(click_recognizer_get_button_id(recognizer) == BUTTON_ID_DOWN)
selected_token++;
else
selected_token--;
2016-04-18 04:25:36 -04:00
2020-05-04 18:14:41 -04:00
// If selected token is outside of range, wrap around
if(selected_token < 0)
selected_token = tokenCount() - 1;
else if(selected_token >= tokenCount())
selected_token = 0;
updateText();
2016-04-18 04:25:36 -04:00
}
2020-05-04 18:14:41 -04:00
// Backspace if possible, otherwise close the app
2020-05-03 21:24:36 -04:00
static void back_handler(ClickRecognizerRef recognizer, void *context) {
if(mytext[0] == '\0') {
window_stack_remove(window_stack_get_top_window(), true);
} else {
2020-05-04 18:14:41 -04:00
int8_t i = 0;
2020-05-03 21:24:36 -04:00
while(mytext[++i] != '\0') { ; }
mytext[i-1] = '\0';
updateText();
}
}
2016-04-18 04:25:36 -04:00
// Adds the current string to the main string
static void enter(){
strcat(mytext, getToken(selected_token));
selected_token = 0;
updateText();
}
2020-05-04 18:14:41 -04:00
// Calculate result, display it and reset
2016-04-18 04:25:36 -04:00
static void calculate(){
2020-05-03 17:00:45 -04:00
Object obj = parseEval(mytext, &env);
2020-05-04 10:03:35 -04:00
char temp[MAX_LENGTH-2] = "";
2020-05-04 18:14:41 -04:00
2020-05-04 10:03:35 -04:00
stringObj(temp, &obj);
snprintf(resulttext, MAX_LENGTH, "R:%s", temp);
2020-05-03 17:00:45 -04:00
selected_token = 0;
2020-05-03 21:24:36 -04:00
text_layer_set_text(s_result_text_layer, resulttext);
2016-04-18 04:25:36 -04:00
}
// Button press handler
static void select_handler(ClickRecognizerRef recognizer, void *context){
if(selected_token == sizeof(tokens) / sizeof(tokens[0]) - 1)
calculate();
else
enter();
}
static void click_config_provider(void *context) {
// Register click handlers
window_single_repeating_click_subscribe(BUTTON_ID_UP, 100, up_down_handler);
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 100, up_down_handler);
window_single_click_subscribe(BUTTON_ID_SELECT, select_handler);
2020-05-03 21:24:36 -04:00
window_single_click_subscribe(BUTTON_ID_BACK, back_handler);
2016-04-18 04:25:36 -04:00
}
static void init(void) {
// Create a window and get information about the window
s_window = window_create();
2020-05-04 18:14:41 -04:00
2016-04-18 04:25:36 -04:00
// Register click config provider
window_set_click_config_provider(s_window, click_config_provider);
// Input text layer setup
2020-05-03 21:24:36 -04:00
GRect text_bounds = GRect(6, 6, 132, 127);
2016-04-18 04:25:36 -04:00
s_input_text_layer = text_layer_create(text_bounds);
text_layer_set_text(s_input_text_layer, getToken(1));
2020-05-03 21:24:36 -04:00
text_layer_set_font(s_input_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
2016-04-18 04:25:36 -04:00
layer_add_child(window_get_root_layer(s_window), text_layer_get_layer(s_input_text_layer));
2020-05-03 21:24:36 -04:00
// Result text layer setup
GRect result_bounds = GRect(6, 128, 132, 132);
s_result_text_layer = text_layer_create(result_bounds);
text_layer_set_text(s_result_text_layer, "R: ");
text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
text_layer_set_text_alignment(s_result_text_layer, GTextAlignmentRight);
layer_add_child(window_get_root_layer(s_window), text_layer_get_layer(s_result_text_layer));
2016-04-18 04:25:36 -04:00
// Push the window, setting the window animation to 'true'
window_stack_push(s_window, true);
env = defaultEnv();
2020-05-04 18:14:41 -04:00
// If possible, load the previous code text
if(persist_exists(CODE_PKEY)) {
persist_read_string(CODE_PKEY, mytext, SMAX_LENGTH);
updateText();
}
2016-04-18 04:25:36 -04:00
}
static void deinit(void) {
2020-05-04 18:14:41 -04:00
// Save the current code text
persist_write_string(CODE_PKEY, temptext);
2016-04-18 04:25:36 -04:00
2020-05-04 18:14:41 -04:00
deleteEnv(&env);
text_layer_destroy(s_input_text_layer);
2016-04-18 04:25:36 -04:00
window_destroy(s_window);
}
int main(void) {
init();
app_event_loop();
deinit();
}