Cleaned and reorganized and renamed stuff
This commit is contained in:
parent
199eef7681
commit
bf1ce6e6f6
266
src/calc.c
266
src/calc.c
|
@ -2,43 +2,41 @@
|
|||
#include <limits.h>
|
||||
#include "calc.h"
|
||||
|
||||
static inline int8_t tokenCount() {
|
||||
if(!using_func_tokens)
|
||||
return sizeof(tokens) / sizeof(tokens[0]);
|
||||
/** Text Editing **/
|
||||
|
||||
return sizeof(func_tokens) / sizeof(func_tokens[0]);
|
||||
// Get the number of tokens in the current list
|
||||
static inline int8_t tokenCount()
|
||||
{
|
||||
return using_func_tokens?
|
||||
sizeof(func_tokens) / sizeof(func_tokens[0]) :
|
||||
sizeof(tokens) / sizeof(tokens[0]);
|
||||
}
|
||||
|
||||
static inline char* getToken(int8_t n) {
|
||||
if(!using_func_tokens)
|
||||
return tokens[n % tokenCount()];
|
||||
|
||||
return func_tokens[n % tokenCount()];
|
||||
// Get current token from tokens[] or func_tokens[], as appropriate
|
||||
static inline const char* getToken(int8_t n)
|
||||
{
|
||||
int8_t t = n % tokenCount();
|
||||
return using_func_tokens? func_tokens[t] : tokens[t];
|
||||
}
|
||||
|
||||
// Currently selected button, starts on '('
|
||||
static int8_t selected_token = 1;
|
||||
|
||||
// Update the current code text with the contents of `mytext`,
|
||||
// and add the current selected_token to the end
|
||||
static void updateText()
|
||||
{
|
||||
const char *token = getToken(selected_token);
|
||||
|
||||
strcpy(temptext, mytext);
|
||||
|
||||
const char *token = getToken(selected_token);
|
||||
if(token[0] == ' ') {
|
||||
strcat(temptext, "_");
|
||||
} else if(token[0] == '\n') {
|
||||
strcat(temptext, "\\n");
|
||||
} else {
|
||||
strcat(temptext, token);
|
||||
}
|
||||
strcat(temptext, token[0] == ' ' ? "_": // Display space as underscore
|
||||
token[0] == '\n'? "\\n": // Display newline as \n
|
||||
token); // Display others literally
|
||||
|
||||
text_layer_set_text(s_input_text_layer, temptext);
|
||||
}
|
||||
|
||||
// Button handler
|
||||
static void up_down_handler(ClickRecognizerRef recognizer, void *context){
|
||||
// Cycle through the current list of tokens
|
||||
static void cycle_tokens(ClickRecognizerRef recognizer, void *context)
|
||||
{
|
||||
// Change current token
|
||||
if(click_recognizer_get_button_id(recognizer) == BUTTON_ID_DOWN)
|
||||
selected_token++;
|
||||
|
@ -54,37 +52,41 @@ static void up_down_handler(ClickRecognizerRef recognizer, void *context){
|
|||
updateText();
|
||||
}
|
||||
|
||||
static void backspace()
|
||||
/**
|
||||
* In normal token list, backspace if possible, otherwise return to script list
|
||||
* In function token list, return to normal token list
|
||||
*/
|
||||
static void click_backspace(ClickRecognizerRef recognizer, void *context)
|
||||
{
|
||||
int8_t i = 0;
|
||||
while(mytext[++i] != '\0') { ; }
|
||||
mytext[i-1] = '\0';
|
||||
updateText();
|
||||
}
|
||||
|
||||
// Backspace if possible, otherwise close the app
|
||||
static void back_handler(ClickRecognizerRef recognizer, void *context) {
|
||||
if(!using_func_tokens) {
|
||||
if(mytext[0] == '\0') {
|
||||
window_stack_remove(window_stack_get_top_window(), true);
|
||||
} else {
|
||||
backspace();
|
||||
mytext[strlen(mytext) - 1] = '\0';
|
||||
updateText();
|
||||
}
|
||||
} else {
|
||||
using_func_tokens = 0;
|
||||
using_func_tokens = false;
|
||||
updateText();
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the current string to the main string
|
||||
static void enter(){
|
||||
static void add_token()
|
||||
{
|
||||
strcat(mytext, getToken(selected_token));
|
||||
selected_token = 0;
|
||||
if(using_func_tokens) {
|
||||
using_func_tokens = false;
|
||||
}
|
||||
updateText();
|
||||
}
|
||||
|
||||
/** Code running and saving **/
|
||||
|
||||
// Calculate result, display it and reset
|
||||
static void calculate(){
|
||||
static void calculate()
|
||||
{
|
||||
Object obj = parseEval(mytext, &env);
|
||||
char temp[RESULT_LENGTH-2] = "";
|
||||
|
||||
|
@ -94,21 +96,23 @@ static void calculate(){
|
|||
}
|
||||
|
||||
// Button press handler
|
||||
static void select_handler(ClickRecognizerRef recognizer, void *context){
|
||||
static void click_select(ClickRecognizerRef recognizer, void *context)
|
||||
{
|
||||
if(!using_func_tokens && selected_token == tokenCount() - 1) {
|
||||
calculate();
|
||||
} else if(!using_func_tokens && selected_token == tokenCount() - 2) {
|
||||
using_func_tokens = 1;
|
||||
using_func_tokens = true;
|
||||
selected_token = 0;
|
||||
updateText();
|
||||
} else {
|
||||
enter();
|
||||
add_token();
|
||||
}
|
||||
}
|
||||
|
||||
static void long_select_handler(ClickRecognizerRef recognizer, void *context){
|
||||
int8_t i = 0;
|
||||
while(temptext[++i] != '\0') { ; }
|
||||
// Saves text in editor to persistent storage
|
||||
static void click_save(ClickRecognizerRef recognizer, void *context)
|
||||
{
|
||||
int8_t i = strlen(temptext);
|
||||
for(unsigned j = 0; j < strlen(getToken(selected_token)); j++) {
|
||||
temptext[i-(1 + j)] = '\0';
|
||||
}
|
||||
|
@ -117,89 +121,25 @@ static void long_select_handler(ClickRecognizerRef recognizer, void *context){
|
|||
window_stack_pop(true);
|
||||
}
|
||||
|
||||
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);
|
||||
window_long_click_subscribe(BUTTON_ID_SELECT, 500, long_select_handler, NULL);
|
||||
window_single_click_subscribe(BUTTON_ID_BACK, back_handler);
|
||||
}
|
||||
|
||||
static uint16_t get_num_rows_callback(MenuLayer *menu_layer,
|
||||
uint16_t section_index, void *context) {
|
||||
return NUM_ROWS;
|
||||
}
|
||||
|
||||
static void draw_row_callback(GContext *ctx, const Layer *cell_layer,
|
||||
MenuIndex *cell_index, void *context) {
|
||||
static char s_buff[16];
|
||||
snprintf(s_buff, sizeof(s_buff), "Script %d", 1 + (int)cell_index->row);
|
||||
|
||||
// Draw this row's index
|
||||
menu_cell_basic_draw(ctx, cell_layer, s_buff, NULL, NULL);
|
||||
}
|
||||
|
||||
static int16_t get_cell_height_callback(struct MenuLayer *menu_layer,
|
||||
MenuIndex *cell_index, void *context) {
|
||||
const int16_t cell_height = 44;
|
||||
return cell_height;
|
||||
}
|
||||
|
||||
void code_window_push() {
|
||||
if(!s_code_window) {
|
||||
s_code_window = window_create();
|
||||
WindowHandlers wh = {
|
||||
.load = code_window_load,
|
||||
.unload = code_window_unload };
|
||||
window_set_window_handlers(s_code_window, wh);
|
||||
}
|
||||
|
||||
window_stack_push(s_code_window, true);
|
||||
}
|
||||
|
||||
static void select_callback(struct MenuLayer *menu_layer,
|
||||
MenuIndex *cell_index, void *context)
|
||||
// Sets the code_window click functions
|
||||
static void code_click_subscribe(void *context)
|
||||
{
|
||||
current_code = cell_index->row;
|
||||
code_window_push();
|
||||
window_single_repeating_click_subscribe(BUTTON_ID_UP, 100, cycle_tokens);
|
||||
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 100, cycle_tokens);
|
||||
window_single_click_subscribe(BUTTON_ID_SELECT, click_select);
|
||||
window_long_click_subscribe(BUTTON_ID_SELECT, 500, click_save, NULL);
|
||||
window_single_click_subscribe(BUTTON_ID_BACK, click_backspace);
|
||||
}
|
||||
|
||||
static void menu_load(Window *window)
|
||||
{
|
||||
Layer *window_layer = window_get_root_layer(window);
|
||||
GRect bounds = layer_get_bounds(window_layer);
|
||||
|
||||
s_menu_layer = menu_layer_create(bounds);
|
||||
menu_layer_set_click_config_onto_window(s_menu_layer, window);
|
||||
#if defined(PBL_COLOR)
|
||||
menu_layer_set_normal_colors(s_menu_layer, GColorBlack, GColorWhite);
|
||||
menu_layer_set_highlight_colors(s_menu_layer, GColorDukeBlue, GColorWhite);
|
||||
#endif
|
||||
menu_layer_set_callbacks(s_menu_layer, NULL, (MenuLayerCallbacks) {
|
||||
.get_num_rows = get_num_rows_callback,
|
||||
.draw_row = draw_row_callback,
|
||||
.get_cell_height = get_cell_height_callback,
|
||||
.select_click = select_callback,
|
||||
});
|
||||
layer_add_child(window_layer, menu_layer_get_layer(s_menu_layer));
|
||||
}
|
||||
|
||||
static void menu_unload(Window *window)
|
||||
{
|
||||
menu_layer_destroy(s_menu_layer);
|
||||
}
|
||||
|
||||
void code_window_load(Window *window)
|
||||
static void code_window_load(Window *window)
|
||||
{
|
||||
Layer *window_layer = window_get_root_layer(window);
|
||||
GRect bounds = layer_get_bounds(window_layer);
|
||||
|
||||
// Register click config provider
|
||||
window_set_click_config_provider(s_code_window, click_config_provider);
|
||||
window_set_click_config_provider(s_code_window, code_click_subscribe);
|
||||
|
||||
// Input text layer setup
|
||||
// GRect text_bounds = GRect(6, 6, 132, 127);
|
||||
s_input_text_layer = text_layer_create(bounds);
|
||||
text_layer_set_text(s_input_text_layer, getToken(1));
|
||||
text_layer_set_font(s_input_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
|
||||
|
@ -223,7 +163,7 @@ void code_window_load(Window *window)
|
|||
}
|
||||
}
|
||||
|
||||
void code_window_unload(Window *window)
|
||||
static void code_window_unload(Window *window)
|
||||
{
|
||||
// Save the current code text
|
||||
persist_write_string(current_code, temptext);
|
||||
|
@ -235,13 +175,86 @@ void code_window_unload(Window *window)
|
|||
s_code_window = NULL;
|
||||
}
|
||||
|
||||
void custom_load(Window *window)
|
||||
void code_window_push()
|
||||
{
|
||||
if(!s_code_window) {
|
||||
s_code_window = window_create();
|
||||
WindowHandlers wh = {
|
||||
.load = code_window_load,
|
||||
.unload = code_window_unload };
|
||||
window_set_window_handlers(s_code_window, wh);
|
||||
}
|
||||
|
||||
window_stack_push(s_code_window, true);
|
||||
}
|
||||
|
||||
/** Menu Window **/
|
||||
|
||||
static void select_callback(struct MenuLayer *menu_layer,
|
||||
MenuIndex *cell_index, void *context)
|
||||
{
|
||||
current_code = cell_index->row;
|
||||
code_window_push();
|
||||
}
|
||||
|
||||
static uint16_t get_num_rows_callback(MenuLayer *menu_layer,
|
||||
uint16_t section_index, void *context)
|
||||
{
|
||||
return SCRIPT_COUNT;
|
||||
}
|
||||
|
||||
static void draw_row_callback(GContext *ctx, const Layer *cell_layer,
|
||||
MenuIndex *cell_index, void *context)
|
||||
{
|
||||
static char s_buff[16];
|
||||
snprintf(s_buff, sizeof(s_buff), "Script %d", 1 + (int)cell_index->row);
|
||||
|
||||
// Draw this row's index
|
||||
menu_cell_basic_draw(ctx, cell_layer, s_buff, NULL, NULL);
|
||||
}
|
||||
|
||||
static int16_t get_cell_height_callback(struct MenuLayer *menu_layer,
|
||||
MenuIndex *cell_index, void *context)
|
||||
{
|
||||
return CELL_HEIGHT;
|
||||
}
|
||||
|
||||
static void menu_load(Window *window)
|
||||
{
|
||||
Layer *window_layer = window_get_root_layer(window);
|
||||
GRect bounds = layer_get_bounds(window_layer);
|
||||
|
||||
s_menu_layer = menu_layer_create(bounds);
|
||||
menu_layer_set_click_config_onto_window(s_menu_layer, window);
|
||||
|
||||
#if defined(PBL_COLOR)
|
||||
menu_layer_set_normal_colors(s_menu_layer, GColorBlack, GColorWhite);
|
||||
menu_layer_set_highlight_colors(s_menu_layer, GColorDukeBlue, GColorWhite);
|
||||
#endif
|
||||
|
||||
menu_layer_set_callbacks(s_menu_layer, NULL, (MenuLayerCallbacks) {
|
||||
.get_num_rows = get_num_rows_callback,
|
||||
.draw_row = draw_row_callback,
|
||||
.get_cell_height = get_cell_height_callback,
|
||||
.select_click = select_callback,
|
||||
});
|
||||
layer_add_child(window_layer, menu_layer_get_layer(s_menu_layer));
|
||||
}
|
||||
|
||||
static void menu_unload(Window *window)
|
||||
{
|
||||
menu_layer_destroy(s_menu_layer);
|
||||
}
|
||||
|
||||
/** Custom Window **/
|
||||
|
||||
static void custom_load(Window *window)
|
||||
{
|
||||
Layer *window_layer = window_get_root_layer(window);
|
||||
GRect bounds = layer_get_bounds(window_layer);
|
||||
|
||||
// Register click config provider
|
||||
window_set_click_config_provider(s_custom_window, click_config_provider);
|
||||
window_set_click_config_provider(s_custom_window, code_click_subscribe);
|
||||
|
||||
// Header text layer setup
|
||||
s_heading_text_layer = text_layer_create(bounds);
|
||||
|
@ -255,10 +268,9 @@ void custom_load(Window *window)
|
|||
window_stack_push(s_custom_window, true);
|
||||
}
|
||||
|
||||
void custom_unload(Window *window)
|
||||
static void custom_unload(Window *window)
|
||||
{
|
||||
text_layer_destroy(s_heading_text_layer);
|
||||
//text_layer_destroy(s_input_text_layer);
|
||||
|
||||
window_destroy(window);
|
||||
s_custom_window = NULL;
|
||||
|
@ -284,15 +296,19 @@ Object add_window(Object obj1, Object obj2, struct Environment *env)
|
|||
return numberObject(1);
|
||||
}
|
||||
|
||||
static struct Environment pebbleEnv() {
|
||||
/** General **/
|
||||
|
||||
static struct Environment pebbleEnv()
|
||||
{
|
||||
struct Environment e = defaultEnv();
|
||||
// Needs two args
|
||||
addFunc("window", &add_window, &e);
|
||||
parseEval("(def w (fn (a) (window a 1)))", &e);
|
||||
parseEval("(def win (fn (a) (window a 1)))", &e);
|
||||
return e;
|
||||
}
|
||||
|
||||
static void init(void) {
|
||||
static void init(void)
|
||||
{
|
||||
env = pebbleEnv();
|
||||
s_menu_window = window_create();
|
||||
window_set_window_handlers(s_menu_window, (WindowHandlers) {
|
||||
|
@ -302,13 +318,15 @@ static void init(void) {
|
|||
window_stack_push(s_menu_window, true);
|
||||
}
|
||||
|
||||
static void deinit(void) {
|
||||
static void deinit(void)
|
||||
{
|
||||
deleteEnv(&env);
|
||||
text_layer_destroy(s_input_text_layer);
|
||||
window_destroy(s_menu_window);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int main(void)
|
||||
{
|
||||
init();
|
||||
app_event_loop();
|
||||
deinit();
|
||||
|
|
22
src/calc.h
22
src/calc.h
|
@ -6,9 +6,9 @@
|
|||
|
||||
#define SMAX_LENGTH 256
|
||||
#define RESULT_LENGTH 20
|
||||
#define END_PHRASE "END"
|
||||
#define CELL_HEIGHT 44
|
||||
|
||||
#define NUM_ROWS 5
|
||||
#define SCRIPT_COUNT 5
|
||||
|
||||
Window *s_menu_window;
|
||||
Window *s_code_window;
|
||||
|
@ -28,6 +28,10 @@ TextLayer *s_list_message_layer;
|
|||
|
||||
int current_code;
|
||||
|
||||
// Currently selected button, starts on '('
|
||||
static int8_t selected_token = 1;
|
||||
|
||||
|
||||
// PebbLisp environment
|
||||
static struct Environment env;
|
||||
|
||||
|
@ -40,7 +44,7 @@ char temptext[SMAX_LENGTH] = "";
|
|||
// The result of execution
|
||||
char resulttext[RESULT_LENGTH] = "";
|
||||
|
||||
char *tokens[] = {
|
||||
const char *tokens[] = {
|
||||
" ", "(", ")",
|
||||
"+ ", "- ", "* ", "/ ",
|
||||
"1","2","3",
|
||||
|
@ -49,21 +53,19 @@ char *tokens[] = {
|
|||
"a", "b", "c", "d", "e",
|
||||
"= ", "< ", "> ",
|
||||
"\"",
|
||||
"cat", "map", "fn", "def", "if", "\n",
|
||||
"cat", "map", "fil",
|
||||
"fn", "def", "if", "\n",
|
||||
"...",
|
||||
END_PHRASE
|
||||
"END"
|
||||
};
|
||||
|
||||
char *func_tokens[] = {
|
||||
const char *func_tokens[] = {
|
||||
"spent ", "window ",
|
||||
"max ", "min ",
|
||||
"sq ", "cube ", "exp "
|
||||
|
||||
};
|
||||
|
||||
int using_func_tokens = 0;
|
||||
|
||||
void code_window_load(Window *window);
|
||||
void code_window_unload(Window *window);
|
||||
bool using_func_tokens = false;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue