diff --git a/README.md b/README.md index a078e9f..5a188e7 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ This is source code for "Percentage" pebble app. It tracks success/fail rates of 9 items. It was designed in cloudpebble. + ## Features @@ -20,5 +21,4 @@ This is source code for "Percentage" pebble app. It tracks success/fail rates of ## Resources * Pixelorama project files (Blue/Red/Green) -* C code -* Silkscreen font \ No newline at end of file +* C code \ No newline at end of file diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..b27af45 --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +# TODO + +* Configurable ORANGE/RED limits +* RED & GREEN theme +* Automatic smaller font to allow more characters? +* add "fail/success" display system (red/green) \ No newline at end of file diff --git a/package.json b/package.json index 235f581..b5e8063 100644 --- a/package.json +++ b/package.json @@ -12,42 +12,11 @@ "displayName": "Percentage", "enableMultiJS": true, "messageKeys": [ - "ITEM_1", - "ITEM_2", - "ITEM_3", - "ITEM_4", - "ITEM_5", - "ITEM_6", - "ITEM_7", - "ITEM_8", - "ITEM_9", - "ITEM_1_SUCCESS", - "ITEM_1_FAIL", - "ITEM_1_PERCENTAGE", - "ITEM_2_SUCCESS", - "ITEM_2_FAIL", - "ITEM_2_PERCENTAGE", - "ITEM_3_SUCCESS", - "ITEM_3_FAIL", - "ITEM_3_PERCENTAGE", - "ITEM_4_SUCCESS", - "ITEM_4_FAIL", - "ITEM_4_PERCENTAGE", - "ITEM_5_SUCCESS", - "ITEM_5_FAIL", - "ITEM_5_PERCENTAGE", - "ITEM_6_SUCCESS", - "ITEM_6_FAIL", - "ITEM_6_PERCENTAGE", - "ITEM_7_SUCCESS", - "ITEM_7_FAIL", - "ITEM_7_PERCENTAGE", - "ITEM_8_SUCCESS", - "ITEM_8_FAIL", - "ITEM_8_PERCENTAGE", - "ITEM_9_SUCCESS", - "ITEM_9_FAIL", - "ITEM_9_PERCENTAGE" + "ITEM_NAME", + "ITEM_SUCCESS", + "ITEM_FAIL", + "ITEM_PERCENTAGE", + "ITEM_REMOVE" ], "projectType": "native", "resources": { diff --git a/screenshots/pic2.png b/screenshots/pic2.png new file mode 100644 index 0000000..7a3e38a Binary files /dev/null and b/screenshots/pic2.png differ diff --git a/src/c/items.c b/src/c/items.c index 3b530e8..981a5c3 100644 --- a/src/c/items.c +++ b/src/c/items.c @@ -1,4 +1,6 @@ #include +#include + #include "items.h" #include "src/c/scrolllayer.h" @@ -41,281 +43,95 @@ item_list_t *items_get() { return &s_items; } +// ------------ HELPERS ------------ +static int str_case_cmp(const char *a, const char *b, size_t n) { + for (size_t i = 0; i < n; i++) { + unsigned char ca = (unsigned char)a[i]; + unsigned char cb = (unsigned char)b[i]; + + int lca = tolower(ca); + int lcb = tolower(cb); + + if (lca != lcb) { + return lca - lcb; + } + if (ca == '\0') { + return 0; + } + } + return 0; +} + // ------------ PHONE ------------ -static void update_items(item_list_t *items, const item_list_t *buffer) { - if (!items || !buffer) { +static void update_items(item_list_t *items, const item_t *item, bool remove) { + if (!items || !item || item->name[0] == '\0') { return; } - // Check existing items + // Find existing item for (int i = 0; i < MAX_ITEMS; i++) { - if (items->items[i].name[0] == '\0') { - continue; - } - - bool found = false; - for (int j = 0; j < MAX_ITEMS; j++) { - if (buffer->items[j].name[0] != '\0' && strcmp(items->items[i].name, buffer->items[j].name) == 0) { - - // Item still exists - items->items[i].show_percentage = buffer->items[j].show_percentage; - found = true; - break; + if (items->items[i].name[0] != '\0' && str_case_cmp(items->items[i].name, item->name, MAX_CHARACTERS) == 0) { + if (remove) { + memset(&items->items[i], 0, sizeof(items->items[i])); + } + else { + items->items[i].show_percentage = item->show_percentage; } - } - - // Item no longer exists - if (!found) { - memset(&items->items[i], 0, sizeof(items->items[i])); + return; } } - // Add items - for (int i = 0; i < MAX_ITEMS; i++) { - if (buffer->items[i].name[0] == '\0') { - continue; - } - - bool found = false; - for (int j = 0; j < MAX_ITEMS; j++) { - if (items->items[j].name[0] != '\0' && strcmp(items->items[j].name, buffer->items[i].name) == 0) { - found = true; + // Not found + if (!remove) { + for (int i = 0; i < MAX_ITEMS; i++) { + if (items->items[i].name[0] == '\0') { + items->items[i] = *item; break; } } - - if (!found) { - for (int j = 0; j < MAX_ITEMS; j++) { - if (items->items[j].name[0] == '\0') { - memcpy(&items->items[j], &buffer->items[i], sizeof(items->items[j])); - break; - } - } - } } - - items_organize(items); } static void inbox_received_handler(DictionaryIterator *iter, void *context) { // Remove scroll layer items scroll_layer_remove_items(); - Tuple *tuple; - item_list_t item_buffer; + Tuple *tuple;; + item_t item; + memset(&item, 0, sizeof(item)); + bool remove = false; // Get the item 1 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_1); + tuple = dict_find(iter, MESSAGE_KEY_ITEM_NAME); if (tuple) { - strncpy(item_buffer.items[0].name, tuple->value->cstring, MAX_CHARACTERS); + strncpy(item.name, tuple->value->cstring, MAX_CHARACTERS); + item.name[MAX_CHARACTERS - 1] = '\0'; } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_1_SUCCESS); + tuple = dict_find(iter, MESSAGE_KEY_ITEM_SUCCESS); if (tuple) { int success = atoi(tuple->value->cstring); if (success < 0) { success = 0; } - item_buffer.items[0].successes = success; + item.successes = success; } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_1_FAIL); + tuple = dict_find(iter, MESSAGE_KEY_ITEM_FAIL); if (tuple) { int fail = atoi(tuple->value->cstring); if (fail < 0) { fail = 0; } - item_buffer.items[0].fails = fail; + item.fails = fail; } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_1_PERCENTAGE); + tuple = dict_find(iter, MESSAGE_KEY_ITEM_PERCENTAGE); if (tuple) { bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[0].show_percentage = show_percentage; + item.show_percentage = show_percentage; } - - // Get the item 2 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_2); + // Add or remove + tuple = dict_find(iter, MESSAGE_KEY_ITEM_REMOVE); if (tuple) { - strncpy(item_buffer.items[1].name, tuple->value->cstring, MAX_CHARACTERS); + remove = tuple->value->int32 != 0; } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_2_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[1].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_2_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[1].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_2_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[1].show_percentage = show_percentage; - } - - // Get the item 3 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_3); - if (tuple) { - strncpy(item_buffer.items[2].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_3_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[2].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_3_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[2].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_3_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[2].show_percentage = show_percentage; - } - - // Get the item 4 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_4); - if (tuple) { - strncpy(item_buffer.items[3].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_4_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[3].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_4_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[3].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_4_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[3].show_percentage = show_percentage; - } - - // Get the item 5 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_5); - if (tuple) { - strncpy(item_buffer.items[4].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_5_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[4].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_5_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[4].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_5_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[4].show_percentage = show_percentage; - } - - // Get the item 6 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_6); - if (tuple) { - strncpy(item_buffer.items[5].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_6_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[5].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_6_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[5].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_6_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[5].show_percentage = show_percentage; - } - - // Get the item 7 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_7); - if (tuple) { - strncpy(item_buffer.items[6].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_7_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[6].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_7_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[6].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_7_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[6].show_percentage = show_percentage; - } - - // Get the item 8 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_8); - if (tuple) { - strncpy(item_buffer.items[7].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_8_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[7].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_8_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[7].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_8_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[7].show_percentage = show_percentage; - } - - // Get the item 9 - tuple = dict_find(iter, MESSAGE_KEY_ITEM_9); - if (tuple) { - strncpy(item_buffer.items[8].name, tuple->value->cstring, MAX_CHARACTERS); - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_9_SUCCESS); - if (tuple) { - int success = atoi(tuple->value->cstring); - if (success < 0) { success = 0; } - item_buffer.items[8].successes = success; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_9_FAIL); - if (tuple) { - int fail = atoi(tuple->value->cstring); - if (fail < 0) { fail = 0; } - item_buffer.items[8].fails = fail; - } - tuple = dict_find(iter, MESSAGE_KEY_ITEM_9_PERCENTAGE); - if (tuple) { - bool show_percentage = tuple->value->int32 != 0; - item_buffer.items[8].show_percentage = show_percentage; - } - - // Organize buffer - items_organize(&item_buffer); // Update list from buffer - update_items(&s_items, &item_buffer); + update_items(&s_items, &item, remove); // Save the items to NVM items_organize(&s_items); diff --git a/src/pkjs/config.js b/src/pkjs/config.js index 6be4d1a..542d3b4 100644 --- a/src/pkjs/config.js +++ b/src/pkjs/config.js @@ -5,7 +5,7 @@ module.exports = [ }, { "type": "text", - "defaultValue": "Character limit is 10. If numbers go higher than 1000, use percentage." + "defaultValue": "Add/remove up to 9 items. Character limit is 10. If numbers go higher than 1000, use percentage." }, { @@ -13,293 +13,35 @@ module.exports = [ "items": [ { "type": "heading", - "defaultValue": "Item 1" + "defaultValue": "Item" }, { "type": "input", - "messageKey": "ITEM_1", + "messageKey": "ITEM_NAME", "defaultValue": "" }, { "type": "input", - "messageKey": "ITEM_1_SUCCESS", + "messageKey": "ITEM_SUCCESS", "label": "Success", "defaultValue": "0" }, { "type": "input", - "messageKey": "ITEM_1_FAIL", + "messageKey": "ITEM_FAIL", "label": "Fail", "defaultValue": "0" }, { "type": "toggle", - "messageKey": "ITEM_1_PERCENTAGE", + "messageKey": "ITEM_PERCENTAGE", "label": "Show percentage", "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 2" - }, - { - "type": "input", - "messageKey": "ITEM_2", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_2_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_2_FAIL", - "label": "Fail", - "defaultValue": "0" }, { "type": "toggle", - "messageKey": "ITEM_2_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 3" - }, - { - "type": "input", - "messageKey": "ITEM_3", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_3_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_3_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_3_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 4" - }, - { - "type": "input", - "messageKey": "ITEM_4", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_4_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_4_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_4_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 5" - }, - { - "type": "input", - "messageKey": "ITEM_5", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_5_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_5_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_5_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 6" - }, - { - "type": "input", - "messageKey": "ITEM_6", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_6_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_6_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_6_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 7" - }, - { - "type": "input", - "messageKey": "ITEM_7", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_7_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_7_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_7_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 8" - }, - { - "type": "input", - "messageKey": "ITEM_8", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_8_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_8_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_8_PERCENTAGE", - "label": "Show percentage", - "defaultValue": false - } - ] - }, - - { - "type": "section", - "items": [ - { - "type": "heading", - "defaultValue": "Item 9" - }, - { - "type": "input", - "messageKey": "ITEM_9", - "defaultValue": "" - }, - { - "type": "input", - "messageKey": "ITEM_9_SUCCESS", - "label": "Success", - "defaultValue": "0" - }, - { - "type": "input", - "messageKey": "ITEM_9_FAIL", - "label": "Fail", - "defaultValue": "0" - }, - { - "type": "toggle", - "messageKey": "ITEM_9_PERCENTAGE", - "label": "Show percentage", + "messageKey": "ITEM_REMOVE", + "label": "Remove item", "defaultValue": false } ]