2016-04-18 04:25:36 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <limits.h>
|
2020-08-09 15:03:02 -04:00
|
|
|
|
|
|
|
#include "pebcom.h"
|
2021-07-21 11:26:04 -04:00
|
|
|
#include "object.h"
|
2020-08-09 15:03:02 -04:00
|
|
|
#include "pebbleobject.h"
|
2016-04-18 04:25:36 -04:00
|
|
|
#include "calc.h"
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Custom layers that users can build
|
2020-08-09 15:03:02 -04:00
|
|
|
Window *s_custom_window;
|
|
|
|
TextLayer *s_heading_text_layer;
|
|
|
|
char header[30] = "";
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Code display
|
|
|
|
Window *s_code_window;
|
2020-08-09 15:03:02 -04:00
|
|
|
TextLayer *s_input_text_layer;
|
|
|
|
TextLayer *s_result_text_layer;
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Script selection
|
|
|
|
Window *s_script_menu_window;
|
|
|
|
MenuLayer *s_script_select_layer;
|
|
|
|
int current_script_num;
|
2020-08-09 15:03:02 -04:00
|
|
|
|
|
|
|
// PebbLisp environment
|
|
|
|
static struct Environment env;
|
|
|
|
|
2021-07-22 09:32:14 -04:00
|
|
|
// The displayed/processed code text
|
2021-07-15 20:20:36 -04:00
|
|
|
char displayed_code[SMAX_LENGTH] = "";
|
2021-07-22 09:32:14 -04:00
|
|
|
int excess_chars = 1;
|
2020-08-09 15:03:02 -04:00
|
|
|
|
|
|
|
// The result of execution
|
2021-07-15 20:33:17 -04:00
|
|
|
#define RESULT_PREFIX "R:"
|
|
|
|
char result_text[RESULT_LENGTH] = RESULT_PREFIX;
|
2020-08-09 15:03:02 -04:00
|
|
|
|
|
|
|
const char *tokens[] = {
|
|
|
|
" ", "(", ")",
|
|
|
|
"+ ", "- ", "* ", "/ ",
|
|
|
|
"1","2","3",
|
|
|
|
"4","5","6",
|
|
|
|
"7","8","9", "0", "x",
|
|
|
|
"a", "b", "c", "d", "e",
|
|
|
|
"= ", "< ", "> ",
|
|
|
|
"\"",
|
|
|
|
"s",
|
2021-07-15 20:20:36 -04:00
|
|
|
"cat ", "map ", "fil ",
|
|
|
|
"fn ", "def ", "if ", "\n",
|
2020-08-09 15:03:02 -04:00
|
|
|
"...",
|
|
|
|
"END"
|
|
|
|
};
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Currently selected button, starts on '('
|
|
|
|
static int8_t selected_token = 1;
|
|
|
|
|
2020-08-09 15:03:02 -04:00
|
|
|
const char *func_tokens[] = {
|
2021-07-22 09:32:14 -04:00
|
|
|
"window ",
|
2020-08-09 15:03:02 -04:00
|
|
|
"sc ", "cw ", "pw ", "rw ", "atl ", "utl ",
|
|
|
|
"sec ", "mnt ", "hr ", "hrt ", "vibe ", "sub "
|
|
|
|
};
|
|
|
|
|
|
|
|
bool using_func_tokens = false;
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Size of messages to/from the phone app
|
|
|
|
const uint32_t inbox_size = 1024;
|
|
|
|
const uint32_t outbox_size = 1024;
|
2020-08-09 15:03:02 -04:00
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
/** Text Editing **/
|
2020-05-21 12:57:24 -04:00
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// Get the number of tokens in the current list
|
|
|
|
static inline int8_t tokenCount()
|
|
|
|
{
|
|
|
|
return using_func_tokens?
|
2021-07-22 09:32:14 -04:00
|
|
|
sizeof(func_tokens) / sizeof(func_tokens[0]) :
|
|
|
|
sizeof(tokens) / sizeof(tokens[0]);
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// 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];
|
2020-05-04 18:14:41 -04:00
|
|
|
}
|
|
|
|
|
2021-07-22 09:32:14 -04:00
|
|
|
static void trim(size_t len)
|
|
|
|
{
|
|
|
|
size_t end = strlen(displayed_code) - 1;
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
|
|
displayed_code[end - i] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Update the current code text with the contents of `current_code_text`,
|
2020-05-04 18:14:41 -04:00
|
|
|
// and add the current selected_token to the end
|
2016-04-18 04:25:36 -04:00
|
|
|
static void updateText()
|
|
|
|
{
|
2021-07-22 09:32:14 -04:00
|
|
|
trim(excess_chars);
|
2020-05-22 01:04:00 -04:00
|
|
|
const char *token = getToken(selected_token);
|
|
|
|
|
2021-07-22 09:32:14 -04:00
|
|
|
const char* add =
|
2021-07-15 20:20:36 -04:00
|
|
|
token[0] == ' ' ? "_": // Display space as underscore
|
|
|
|
token[0] == '\n'? "\\n": // Display newline as \n
|
2021-07-22 09:32:14 -04:00
|
|
|
token; // Display others literally
|
|
|
|
|
|
|
|
strcat(displayed_code, add);
|
|
|
|
excess_chars = strlen(add);
|
2016-04-18 04:25:36 -04:00
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
text_layer_set_text(s_input_text_layer, displayed_code);
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// Cycle through the current list of tokens
|
|
|
|
static void cycle_tokens(ClickRecognizerRef recognizer, void *context)
|
|
|
|
{
|
2020-05-04 18:14:41 -04:00
|
|
|
// Change current token
|
2021-07-15 20:20:36 -04:00
|
|
|
if(click_recognizer_get_button_id(recognizer) == BUTTON_ID_DOWN) {
|
2020-05-04 18:14:41 -04:00
|
|
|
selected_token++;
|
2021-07-15 20:20:36 -04:00
|
|
|
} else {
|
2020-05-04 18:14:41 -04:00
|
|
|
selected_token--;
|
2021-07-15 20:20:36 -04:00
|
|
|
}
|
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
|
2021-07-15 20:20:36 -04:00
|
|
|
if(selected_token < 0) {
|
2020-05-04 18:14:41 -04:00
|
|
|
selected_token = tokenCount() - 1;
|
2021-07-15 20:20:36 -04:00
|
|
|
} else if(selected_token >= tokenCount()) {
|
2020-05-04 18:14:41 -04:00
|
|
|
selected_token = 0;
|
2021-07-15 20:20:36 -04:00
|
|
|
}
|
2020-05-04 18:14:41 -04:00
|
|
|
|
|
|
|
updateText();
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2021-07-15 19:43:46 -04:00
|
|
|
static GFont tiny_font;
|
2020-08-02 16:16:26 -04:00
|
|
|
static const char *fonts[] = {
|
|
|
|
FONT_KEY_GOTHIC_28_BOLD,
|
|
|
|
FONT_KEY_GOTHIC_24_BOLD,
|
|
|
|
FONT_KEY_GOTHIC_18_BOLD,
|
|
|
|
FONT_KEY_GOTHIC_14_BOLD
|
|
|
|
};
|
|
|
|
|
|
|
|
static const int smallestFont = 3;
|
|
|
|
|
|
|
|
static void adjustFont()
|
|
|
|
{
|
|
|
|
int i = 0;
|
2020-08-02 16:53:30 -04:00
|
|
|
int size = 0;
|
2021-07-15 20:20:36 -04:00
|
|
|
while(displayed_code[i++]) {
|
|
|
|
if(displayed_code[i] == '\n')
|
2020-08-02 16:53:30 -04:00
|
|
|
size += 10;
|
|
|
|
size++;
|
|
|
|
}
|
2021-07-15 19:43:46 -04:00
|
|
|
// Use various system fonts for most text
|
|
|
|
if(size <= 100) {
|
|
|
|
int f = size < 50 ? smallestFont - 3 :
|
|
|
|
size < 80 ? smallestFont - 2 :
|
|
|
|
size < 100 ? smallestFont - 1 :
|
|
|
|
smallestFont;
|
|
|
|
text_layer_set_font(s_input_text_layer,
|
|
|
|
fonts_get_system_font(fonts[f]));
|
|
|
|
} else {
|
|
|
|
// Use custom extra small font for lots of text
|
|
|
|
text_layer_set_font(s_input_text_layer, tiny_font);
|
|
|
|
}
|
2020-08-02 16:16:26 -04:00
|
|
|
}
|
|
|
|
|
2020-08-03 09:17:49 -04:00
|
|
|
static void custom_unload(Window *window)
|
|
|
|
{
|
|
|
|
text_layer_destroy(s_heading_text_layer);
|
|
|
|
|
|
|
|
window_destroy(window);
|
|
|
|
s_custom_window = NULL;
|
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
/**
|
|
|
|
* 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)
|
2020-05-21 12:57:24 -04:00
|
|
|
{
|
2020-08-03 09:17:49 -04:00
|
|
|
if(s_custom_window) {
|
|
|
|
window_stack_remove(s_custom_window, true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-21 12:57:24 -04:00
|
|
|
if(!using_func_tokens) {
|
2021-07-22 09:32:14 -04:00
|
|
|
if(displayed_code[0] == '\0') {
|
2020-05-21 12:57:24 -04:00
|
|
|
window_stack_remove(window_stack_get_top_window(), true);
|
|
|
|
} else {
|
2021-07-22 09:32:14 -04:00
|
|
|
trim(excess_chars + 1);
|
|
|
|
excess_chars = 0;
|
2020-05-22 01:04:00 -04:00
|
|
|
updateText();
|
2020-05-21 12:57:24 -04:00
|
|
|
}
|
2020-05-03 21:24:36 -04:00
|
|
|
} else {
|
2020-05-22 01:04:00 -04:00
|
|
|
using_func_tokens = false;
|
2020-05-03 21:24:36 -04:00
|
|
|
updateText();
|
|
|
|
}
|
2020-08-02 16:16:26 -04:00
|
|
|
adjustFont();
|
2020-05-03 21:24:36 -04:00
|
|
|
}
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Adds the current token string to the main code string
|
2020-05-22 01:04:00 -04:00
|
|
|
static void add_token()
|
|
|
|
{
|
2021-07-22 09:32:14 -04:00
|
|
|
strcat(displayed_code, getToken(selected_token));
|
2016-04-18 04:25:36 -04:00
|
|
|
selected_token = 0;
|
2020-05-22 01:04:00 -04:00
|
|
|
if(using_func_tokens) {
|
|
|
|
using_func_tokens = false;
|
|
|
|
}
|
2020-08-02 16:16:26 -04:00
|
|
|
|
2016-04-18 04:25:36 -04:00
|
|
|
updateText();
|
2020-08-02 16:16:26 -04:00
|
|
|
adjustFont();
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
/** Code running and saving **/
|
|
|
|
|
2020-05-04 18:14:41 -04:00
|
|
|
// Calculate result, display it and reset
|
2020-05-22 01:04:00 -04:00
|
|
|
static void calculate()
|
|
|
|
{
|
2021-07-21 11:26:04 -04:00
|
|
|
char temp[RESULT_LENGTH + 2] = "";
|
2020-05-04 18:14:41 -04:00
|
|
|
|
2021-07-22 09:32:14 -04:00
|
|
|
trim(excess_chars);
|
|
|
|
excess_chars = 0;
|
|
|
|
Object obj = parseEval(displayed_code, &env);
|
|
|
|
updateText();
|
|
|
|
|
2021-07-21 11:26:04 -04:00
|
|
|
stringNObj(temp, &obj, RESULT_LENGTH);
|
|
|
|
if(obj.type == TYPE_ERROR) {
|
|
|
|
text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD));
|
|
|
|
} else {
|
|
|
|
text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD));
|
|
|
|
}
|
2021-07-15 20:33:17 -04:00
|
|
|
snprintf(result_text, RESULT_LENGTH, RESULT_PREFIX "%s", temp);
|
2021-07-15 20:20:36 -04:00
|
|
|
text_layer_set_text(s_result_text_layer, result_text);
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Button press handler
|
2020-05-22 01:04:00 -04:00
|
|
|
static void click_select(ClickRecognizerRef recognizer, void *context)
|
|
|
|
{
|
2020-05-21 12:57:24 -04:00
|
|
|
if(!using_func_tokens && selected_token == tokenCount() - 1) {
|
2016-04-18 04:25:36 -04:00
|
|
|
calculate();
|
2020-05-21 12:57:24 -04:00
|
|
|
} else if(!using_func_tokens && selected_token == tokenCount() - 2) {
|
2020-05-22 01:04:00 -04:00
|
|
|
using_func_tokens = true;
|
2020-05-21 12:57:24 -04:00
|
|
|
selected_token = 0;
|
|
|
|
updateText();
|
|
|
|
} else {
|
2020-05-22 01:04:00 -04:00
|
|
|
add_token();
|
2020-05-21 12:57:24 -04:00
|
|
|
}
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// Saves text in editor to persistent storage
|
|
|
|
static void click_save(ClickRecognizerRef recognizer, void *context)
|
|
|
|
{
|
2021-07-15 20:20:36 -04:00
|
|
|
int8_t i = strlen(displayed_code);
|
2021-07-21 11:26:04 -04:00
|
|
|
unsigned token_len = strlen(getToken(selected_token));
|
|
|
|
printf("%s", displayed_code);
|
|
|
|
for(unsigned j = 0; j < token_len; j++) {
|
2021-07-15 20:20:36 -04:00
|
|
|
displayed_code[i-(1 + j)] = '\0';
|
2021-07-21 11:26:04 -04:00
|
|
|
printf("%s", displayed_code);
|
2020-05-21 12:57:24 -04:00
|
|
|
}
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
persist_write_string(current_script_num, displayed_code);
|
2020-05-05 19:21:54 -04:00
|
|
|
window_stack_pop(true);
|
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// Sets the code_window click functions
|
|
|
|
static void code_click_subscribe(void *context)
|
|
|
|
{
|
|
|
|
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);
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2021-07-21 14:49:29 -04:00
|
|
|
#ifdef LOW_MEM
|
2021-07-21 15:48:41 -04:00
|
|
|
#define TIME_FUNC \
|
|
|
|
"(def time (fn ()(utl tt \n"\
|
|
|
|
" (cat \"Hey, it's \" \n"\
|
|
|
|
" (hrt) \":\" (mnt)\n" \
|
|
|
|
"))))\n"
|
2021-07-21 14:49:29 -04:00
|
|
|
#else
|
2021-07-21 15:48:41 -04:00
|
|
|
#define TIME_FUNC \
|
|
|
|
"(def time (fn () ((def m (mnt)) (utl tt \n"\
|
|
|
|
" (cat \"Hey, it's \"\n"\
|
|
|
|
" (hrt) \":\" (if (< m 10) \"0\" \"\") m)\n"\
|
|
|
|
"))))\n"
|
2021-07-21 14:49:29 -04:00
|
|
|
#endif
|
|
|
|
|
2021-07-21 15:48:41 -04:00
|
|
|
#define FORCE_TEXT TIME_FUNC \
|
2021-07-15 19:43:46 -04:00
|
|
|
"(def ww (cw))\n" \
|
|
|
|
"(def tt (atl ww \":\"))\n" \
|
|
|
|
"(pw ww)\n" \
|
|
|
|
"(sub time 2)"
|
2020-08-09 15:03:02 -04:00
|
|
|
|
|
|
|
// Remove to re-enable
|
|
|
|
#undef FORCE_TEXT
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
static void code_window_load(Window *window)
|
|
|
|
{
|
|
|
|
Layer *window_layer = window_get_root_layer(window);
|
|
|
|
GRect bounds = layer_get_bounds(window_layer);
|
2020-05-05 19:21:54 -04:00
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// Register click config provider
|
|
|
|
window_set_click_config_provider(s_code_window, code_click_subscribe);
|
2020-05-05 19:21:54 -04:00
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
// Input text layer setup
|
|
|
|
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));
|
|
|
|
layer_add_child(window_get_root_layer(s_code_window), text_layer_get_layer(s_input_text_layer));
|
|
|
|
|
|
|
|
// Result text layer setup
|
2021-07-15 19:43:46 -04:00
|
|
|
GRect result_bounds = GRect(6, 148, 132, 132);
|
2020-05-22 01:04:00 -04:00
|
|
|
s_result_text_layer = text_layer_create(result_bounds);
|
2021-07-15 20:33:17 -04:00
|
|
|
text_layer_set_text(s_result_text_layer, result_text);
|
2020-05-22 01:04:00 -04:00
|
|
|
text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD));
|
|
|
|
text_layer_set_text_alignment(s_result_text_layer, GTextAlignmentRight);
|
|
|
|
layer_add_child(window_get_root_layer(s_code_window), text_layer_get_layer(s_result_text_layer));
|
|
|
|
|
|
|
|
// Push the window, setting the window animation to 'true'
|
|
|
|
window_stack_push(s_code_window, true);
|
|
|
|
|
|
|
|
// If possible, load the previous code text
|
2020-08-09 15:03:02 -04:00
|
|
|
#ifdef FORCE_TEXT
|
2021-07-22 09:32:14 -04:00
|
|
|
strncpy(displayed_code, FORCE_TEXT, SMAX_LENGTH);
|
2020-08-09 15:03:02 -04:00
|
|
|
updateText();
|
|
|
|
adjustFont();
|
|
|
|
#else
|
2021-07-15 20:20:36 -04:00
|
|
|
if(persist_exists(current_script_num)) {
|
2021-07-22 09:32:14 -04:00
|
|
|
persist_read_string(current_script_num, displayed_code, SMAX_LENGTH);
|
2020-05-22 01:04:00 -04:00
|
|
|
updateText();
|
2020-08-02 16:16:26 -04:00
|
|
|
adjustFont();
|
2020-05-22 01:04:00 -04:00
|
|
|
}
|
2020-08-09 15:03:02 -04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void debug_result(const char* d) {
|
2021-07-15 20:20:36 -04:00
|
|
|
snprintf(result_text, RESULT_LENGTH, "%s", d);
|
|
|
|
text_layer_set_text(s_result_text_layer, result_text);
|
2020-08-09 15:03:02 -04:00
|
|
|
psleep(300);
|
2020-05-05 19:21:54 -04:00
|
|
|
}
|
|
|
|
|
2020-08-04 13:30:40 -04:00
|
|
|
static Object run_script(Object script_num, Object obj, struct Environment *e) {
|
|
|
|
int n = script_num.number - 1;
|
|
|
|
if(persist_exists(n)) {
|
|
|
|
char *code = malloc(sizeof(char) * SMAX_LENGTH);
|
|
|
|
persist_read_string(n, code, SMAX_LENGTH);
|
|
|
|
Object o = parseEval(code, e);
|
|
|
|
free(code);
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
return errorObject(SCRIPT_NOT_FOUND);
|
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
static void code_window_unload(Window *window)
|
|
|
|
{
|
|
|
|
// Save the current code text
|
2021-07-15 20:20:36 -04:00
|
|
|
persist_write_string(current_script_num, displayed_code);
|
2020-05-22 01:04:00 -04:00
|
|
|
|
|
|
|
text_layer_destroy(s_result_text_layer);
|
|
|
|
text_layer_destroy(s_input_text_layer);
|
|
|
|
|
|
|
|
window_destroy(window);
|
|
|
|
s_code_window = NULL;
|
2020-05-05 19:21:54 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
void code_window_push()
|
|
|
|
{
|
2020-05-11 01:15:24 -04:00
|
|
|
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);
|
2020-05-05 19:21:54 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
/** Menu Window **/
|
|
|
|
|
2020-05-05 19:21:54 -04:00
|
|
|
static void select_callback(struct MenuLayer *menu_layer,
|
|
|
|
MenuIndex *cell_index, void *context)
|
|
|
|
{
|
2021-07-15 20:20:36 -04:00
|
|
|
current_script_num = cell_index->row;
|
2020-05-05 19:21:54 -04:00
|
|
|
code_window_push();
|
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-07-21 11:26:04 -04:00
|
|
|
static void script_menu_load(Window *window)
|
2020-05-05 19:21:54 -04:00
|
|
|
{
|
2020-05-11 01:15:24 -04:00
|
|
|
Layer *window_layer = window_get_root_layer(window);
|
|
|
|
GRect bounds = layer_get_bounds(window_layer);
|
2020-05-05 19:21:54 -04:00
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
s_script_select_layer = menu_layer_create(bounds);
|
|
|
|
menu_layer_set_click_config_onto_window(s_script_select_layer, window);
|
2020-05-22 01:04:00 -04:00
|
|
|
|
|
|
|
#if defined(PBL_COLOR)
|
2021-07-15 20:20:36 -04:00
|
|
|
menu_layer_set_normal_colors(s_script_select_layer, GColorBlack, GColorWhite);
|
|
|
|
menu_layer_set_highlight_colors(s_script_select_layer, GColorDukeBlue, GColorWhite);
|
2020-05-22 01:04:00 -04:00
|
|
|
#endif
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
menu_layer_set_callbacks(s_script_select_layer, NULL, (MenuLayerCallbacks) {
|
2020-05-11 01:15:24 -04:00
|
|
|
.get_num_rows = get_num_rows_callback,
|
|
|
|
.draw_row = draw_row_callback,
|
|
|
|
.get_cell_height = get_cell_height_callback,
|
|
|
|
.select_click = select_callback,
|
|
|
|
});
|
2021-07-15 20:20:36 -04:00
|
|
|
layer_add_child(window_layer, menu_layer_get_layer(s_script_select_layer));
|
2020-05-05 19:21:54 -04:00
|
|
|
}
|
|
|
|
|
2021-07-21 11:26:04 -04:00
|
|
|
static void script_menu_unload(Window *window)
|
2020-05-05 19:21:54 -04:00
|
|
|
{
|
2021-07-15 20:20:36 -04:00
|
|
|
menu_layer_destroy(s_script_select_layer);
|
2020-05-05 19:21:54 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
/** Custom Window **/
|
2020-05-05 19:21:54 -04:00
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
static void custom_load(Window *window)
|
2020-05-11 01:15:24 -04:00
|
|
|
{
|
|
|
|
Layer *window_layer = window_get_root_layer(window);
|
|
|
|
GRect bounds = layer_get_bounds(window_layer);
|
|
|
|
|
|
|
|
// Register click config provider
|
2020-05-22 01:04:00 -04:00
|
|
|
window_set_click_config_provider(s_custom_window, code_click_subscribe);
|
2020-05-11 01:15:24 -04:00
|
|
|
|
|
|
|
// Header text layer setup
|
|
|
|
s_heading_text_layer = text_layer_create(bounds);
|
|
|
|
text_layer_set_text(s_heading_text_layer, header);
|
|
|
|
text_layer_set_font(s_heading_text_layer,
|
|
|
|
fonts_get_system_font(FONT_KEY_BITHAM_30_BLACK));
|
|
|
|
layer_add_child(window_get_root_layer(s_custom_window),
|
|
|
|
text_layer_get_layer(s_heading_text_layer));
|
|
|
|
|
2021-07-15 20:20:36 -04:00
|
|
|
// Push the window with animations enabled
|
2020-05-11 01:15:24 -04:00
|
|
|
window_stack_push(s_custom_window, true);
|
|
|
|
}
|
|
|
|
|
2021-07-15 20:33:17 -04:00
|
|
|
Object add_window(Object obj1, Object _, struct Environment *env)
|
2020-05-11 01:15:24 -04:00
|
|
|
{
|
2020-05-21 12:57:24 -04:00
|
|
|
printf("ADD_WINDOW\n");
|
2021-07-21 11:26:04 -04:00
|
|
|
stringObj(header, &obj1);
|
2020-05-11 01:15:24 -04:00
|
|
|
|
|
|
|
if(!s_custom_window) {
|
|
|
|
s_custom_window = window_create();
|
|
|
|
WindowHandlers wh = {
|
|
|
|
.load = custom_load,
|
|
|
|
.unload = custom_unload };
|
|
|
|
window_set_window_handlers(s_custom_window, wh);
|
|
|
|
}
|
|
|
|
|
|
|
|
window_stack_push(s_custom_window, true);
|
|
|
|
|
|
|
|
return numberObject(1);
|
|
|
|
}
|
|
|
|
|
2020-08-02 16:53:30 -04:00
|
|
|
static void inbox_received_callback(DictionaryIterator *iter, void *context) {
|
|
|
|
Tuple *script_tuple = dict_find(iter, MESSAGE_KEY_ScriptText);
|
|
|
|
if(script_tuple) {
|
2020-08-03 11:21:04 -04:00
|
|
|
if(!s_code_window) {
|
2021-07-15 20:20:36 -04:00
|
|
|
current_script_num = 0;
|
2020-08-03 11:21:04 -04:00
|
|
|
code_window_push();
|
|
|
|
}
|
2020-08-02 16:53:30 -04:00
|
|
|
char *script_text = script_tuple->value->cstring;
|
2021-07-15 20:20:36 -04:00
|
|
|
snprintf(displayed_code, sizeof(displayed_code), "%s", script_text);
|
2020-08-02 16:53:30 -04:00
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
/** General **/
|
|
|
|
|
|
|
|
static struct Environment pebbleEnv()
|
|
|
|
{
|
2020-05-11 01:15:24 -04:00
|
|
|
struct Environment e = defaultEnv();
|
|
|
|
addFunc("window", &add_window, &e);
|
2020-08-04 13:30:40 -04:00
|
|
|
addFunc("sc", &run_script, &e);
|
2020-08-09 15:03:02 -04:00
|
|
|
addFunc("cw", &createWindow, &e);
|
|
|
|
addFunc("pw", &pushWindow, &e);
|
|
|
|
addFunc("rw", &deleteWindow, &e);
|
|
|
|
addFunc("atl", &addTextLayer, &e);
|
|
|
|
addFunc("utl", &updateTextLayer, &e);
|
|
|
|
addFunc("sec", &getSeconds, &e);
|
|
|
|
addFunc("mnt", &getMinutes, &e);
|
|
|
|
addFunc("hr", &getHours, &e);
|
|
|
|
addFunc("hrt", &getTwelveHours, &e);
|
|
|
|
addFunc("vibe", &doVibe, &e);
|
|
|
|
addFunc("sub", &subscribe, &e);
|
2020-05-11 01:15:24 -04:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
static void init(void)
|
|
|
|
{
|
2020-05-11 01:15:24 -04:00
|
|
|
env = pebbleEnv();
|
2021-07-15 20:20:36 -04:00
|
|
|
s_script_menu_window = window_create();
|
|
|
|
window_set_window_handlers(s_script_menu_window, (WindowHandlers) {
|
2021-07-21 11:26:04 -04:00
|
|
|
.load = script_menu_load,
|
|
|
|
.unload = script_menu_unload
|
2020-05-05 19:21:54 -04:00
|
|
|
});
|
2021-07-15 20:20:36 -04:00
|
|
|
window_stack_push(s_script_menu_window, true);
|
2020-08-02 16:53:30 -04:00
|
|
|
app_message_open(inbox_size, outbox_size);
|
|
|
|
app_message_register_inbox_received(inbox_received_callback);
|
2021-07-21 11:26:04 -04:00
|
|
|
tiny_font = fonts_load_custom_font(
|
|
|
|
resource_get_handle(RESOURCE_ID_FONT_TINY_11));
|
2020-05-05 19:21:54 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
static void deinit(void)
|
|
|
|
{
|
2020-05-04 18:14:41 -04:00
|
|
|
deleteEnv(&env);
|
|
|
|
text_layer_destroy(s_input_text_layer);
|
2021-07-15 20:20:36 -04:00
|
|
|
window_destroy(s_script_menu_window);
|
2016-04-18 04:25:36 -04:00
|
|
|
}
|
|
|
|
|
2020-05-22 01:04:00 -04:00
|
|
|
int main(void)
|
|
|
|
{
|
2016-04-18 04:25:36 -04:00
|
|
|
init();
|
|
|
|
app_event_loop();
|
|
|
|
deinit();
|
|
|
|
}
|