This commit is contained in:
Your Name
2026-09-05 15:31:30 +03:00
parent a092f1dc86
commit 6f530fa222
7 changed files with 88 additions and 158 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

+19 -23
View File
@@ -2,7 +2,6 @@
#include "config.h"
#include "src/c/scrolllayer.h"
#include "src/c/settings.h"
#include "src/c/items.h"
@@ -39,6 +38,25 @@ static void inbox_received_handler(DictionaryIterator *iter, void *context) {
bool show_percentage = tuple->value->int32 != 0;
item.show_percentage = show_percentage;
}
// Get RED/ORANGE limits
tuple = dict_find(iter, MESSAGE_KEY_RED_LIMIT);
if (tuple) {
item.red_limit = tuple->value->int32;
if (item.red_limit < 1) { item.red_limit = 1; }
if (item.red_limit > 100) { item.red_limit = 100; }
}
tuple = dict_find(iter, MESSAGE_KEY_ORANGE_LIMIT);
if (tuple) {
item.orange_limit = tuple->value->int32;
if (item.orange_limit < 1) { item.orange_limit = 1; }
if (item.orange_limit > 100) { item.orange_limit = 100; }
}
if (item.orange_limit < item.red_limit) {
item.orange_limit = item.red_limit;
}
// Add or remove
tuple = dict_find(iter, MESSAGE_KEY_ITEM_REMOVE);
if (tuple) {
@@ -55,28 +73,6 @@ static void inbox_received_handler(DictionaryIterator *iter, void *context) {
// Update the ScrollLayer
scroll_layer_add_items();
scroll_layer_update_scrollbar();
// SETTINGS
settings_t settings_buffer;
memset(&settings_buffer, 0, sizeof(settings_buffer));
// Get settings
tuple = dict_find(iter, MESSAGE_KEY_RED_LIMIT);
if (tuple) {
settings_buffer.red_limit = tuple->value->int32;
}
tuple = dict_find(iter, MESSAGE_KEY_ORANGE_LIMIT);
if (tuple) {
settings_buffer.orange_limit = tuple->value->int32;
}
if (settings_buffer.orange_limit < settings_buffer.red_limit) {
settings_buffer.orange_limit = settings_buffer.red_limit;
}
settings_set(&settings_buffer);
settings_nvm_save();
}
void config_init() {
+8
View File
@@ -72,10 +72,16 @@ void update_items(const item_t *item, bool remove) {
for (int i = 0; i < MAX_ITEMS; i++) {
if (s_items.items[i].name[0] != '\0' && str_case_cmp(s_items.items[i].name, item->name, MAX_CHARACTERS) == 0) {
if (remove) {
// Remove item
memset(&s_items.items[i], 0, sizeof(s_items.items[i]));
}
else {
// Update existing item
s_items.items[i].show_percentage = item->show_percentage;
s_items.items[i].red_limit = item->red_limit;
s_items.items[i].orange_limit = item->orange_limit;
if (item->fails > 0) { s_items.items[i].fails = item->fails; }
if (item->successes > 0) { s_items.items[i].successes = item->successes; }
}
return;
}
@@ -84,7 +90,9 @@ void update_items(const item_t *item, bool remove) {
// Not found
if (!remove) {
for (int i = 0; i < MAX_ITEMS; i++) {
// Find next empty space
if (s_items.items[i].name[0] == '\0') {
// Add item
s_items.items[i] = *item;
break;
}
+3 -1
View File
@@ -4,13 +4,15 @@
// NVM
#define ITEMS_NVM_KEY 1
#define MAX_ITEMS 9
#define MAX_CHARACTERS 32
#define MAX_CHARACTERS 41
typedef struct {
char name[MAX_CHARACTERS+1];
int successes;
int fails;
int red_limit;
int orange_limit;
bool show_percentage;
} item_t;
-7
View File
@@ -4,7 +4,6 @@
#include "src/c/time.h"
#include "src/c/scrolllayer.h"
#include "src/c/config.h"
#include "src/c/settings.h"
static Window *s_main_window;
@@ -64,9 +63,6 @@ static void init() {
// Register app config
config_init();
// Settings load
settings_init();
// MAIN WINDOW CREATE
s_main_window = window_create();
window_set_background_color(s_main_window, GColorBlack);
@@ -81,9 +77,6 @@ static void deinit() {
// Config deinit
config_deinit();
// Settings deinit
settings_deinit();
// MAIN WINDOW DESTROY
window_destroy(s_main_window);
}
+39 -104
View File
@@ -2,7 +2,6 @@
#include "scrolllayer.h"
#include "src/c/colors.h"
#include "src/c/settings.h"
static ScrollLayer *s_scroll_layer;
static Layer *s_scroll_bar_layer;
@@ -31,9 +30,6 @@ static int s_scroll_y;
static int s_scroll_page;
static scroll_items_t s_scroll_items;
// SETTINGS
settings_t *app_settings;
// ------------ SCROLL ------------
static void scroll_up(ClickRecognizerRef recognizer, void *context) {
@@ -102,14 +98,14 @@ static void click_config_provider(void *context) {
}
// ------------ HELPERS ------------
static GColor get_color_float(float val) {
static GColor get_color_float(item_t *item, float val) {
GColor color;
int percentage = (int)(val * 100.0);
if (percentage < app_settings->red_limit) {
if (percentage < item->red_limit) {
color = RED;
}
else if (percentage < app_settings->orange_limit) {
else if (percentage < item->orange_limit) {
color = ORANGE;
}
else {
@@ -186,7 +182,7 @@ void scroll_layer_add_items() {
// Add percentage
int total = s_scroll_items.items->items[i].successes + s_scroll_items.items->items[i].fails;
float percentage = (float)s_scroll_items.items->items[i].successes / total;
GColor color = get_color_float(percentage);
GColor color = get_color_float(&s_scroll_items.items->items[i], percentage);
s_scroll_items.numbers[i] = text_layer_create(GRect(26, (i * ITEM_UI_HEIGHT) + 18, 124, 16));
fill_percentage_buffer(&s_scroll_items, i, total, percentage);
text_layer_set_text(s_scroll_items.numbers[i], s_scroll_items.numbers_buffer[i]);
@@ -269,6 +265,24 @@ void scroll_layer_update_scrollbar() {
layer_mark_dirty(s_scroll_bar_layer);
}
static void touch_update_element(scroll_items_t *items, int element, int *inc_value_ptr) {
// Update numbers
(*inc_value_ptr)++;
int total = items->items->items[element].successes + items->items->items[element].fails;
float percentage = (float)items->items->items[element].successes / total;
GColor color = get_color_float(&items->items->items[element], percentage);
fill_percentage_buffer(items, element, total, percentage);
text_layer_set_text_color(items->numbers[element], color);
text_layer_set_text(items->numbers[element], items->numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(items->success_bars[element]);
*color_ptr = color;
layer_set_frame(items->success_bars[element], bar);
}
// ------------ TOUCH ------------
static void touch_handler(const TouchEvent *event, void *context) {
// Get touch point
@@ -286,21 +300,8 @@ static void touch_handler(const TouchEvent *event, void *context) {
// Change background to pressed
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_plus_pressed_bitmap);
// Update numbers
s_scroll_items.items->items[element].successes++;
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
float percentage = (float)s_scroll_items.items->items[element].successes / total;
GColor color = get_color_float(percentage);
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
text_layer_set_text_color(s_scroll_items.numbers[element], color);
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
*color_ptr = color;
layer_set_frame(s_scroll_items.success_bars[element], bar);
// Update element
touch_update_element(&s_scroll_items, element, &s_scroll_items.items->items[element].successes);
}
else if (event->type == TouchEvent_Liftoff) {
// Reset the background
@@ -318,21 +319,9 @@ static void touch_handler(const TouchEvent *event, void *context) {
if (event->type == TouchEvent_Touchdown) {
// Change background to pressed
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_minus_pressed_bitmap);
s_scroll_items.items->items[element].fails++;
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
float percentage = (float)s_scroll_items.items->items[element].successes / total;
GColor color = get_color_float(percentage);
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
text_layer_set_text_color(s_scroll_items.numbers[element], color);
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
*color_ptr = color;
layer_set_frame(s_scroll_items.success_bars[element], bar);
// Update element
touch_update_element(&s_scroll_items, element, &s_scroll_items.items->items[element].fails);
}
else if (event->type == TouchEvent_Liftoff) {
// Reset the background
@@ -351,21 +340,9 @@ static void touch_handler(const TouchEvent *event, void *context) {
if (event->type == TouchEvent_Touchdown) {
// Change background to pressed
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_plus_pressed_bitmap);
s_scroll_items.items->items[element].successes++;
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
float percentage = (float)s_scroll_items.items->items[element].successes / total;
GColor color = get_color_float(percentage);
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
text_layer_set_text_color(s_scroll_items.numbers[element], color);
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
*color_ptr = color;
layer_set_frame(s_scroll_items.success_bars[element], bar);
// Update element
touch_update_element(&s_scroll_items, element, &s_scroll_items.items->items[element].successes);
}
else if (event->type == TouchEvent_Liftoff) {
// Reset the background
@@ -383,21 +360,9 @@ static void touch_handler(const TouchEvent *event, void *context) {
if (event->type == TouchEvent_Touchdown) {
// Change background to pressed
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_minus_pressed_bitmap);
s_scroll_items.items->items[element].fails++;
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
float percentage = (float)s_scroll_items.items->items[element].successes / total;
GColor color = get_color_float(percentage);
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
text_layer_set_text_color(s_scroll_items.numbers[element], color);
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
*color_ptr = color;
layer_set_frame(s_scroll_items.success_bars[element], bar);
// Update element
touch_update_element(&s_scroll_items, element, &s_scroll_items.items->items[element].fails);
}
else if (event->type == TouchEvent_Liftoff) {
// Reset the background
@@ -416,21 +381,9 @@ static void touch_handler(const TouchEvent *event, void *context) {
if (event->type == TouchEvent_Touchdown) {
// Change background to pressed
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_plus_pressed_bitmap);
s_scroll_items.items->items[element].successes++;
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
float percentage = (float)s_scroll_items.items->items[element].successes / total;
GColor color = get_color_float(percentage);
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
text_layer_set_text_color(s_scroll_items.numbers[element], color);
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
*color_ptr = color;
layer_set_frame(s_scroll_items.success_bars[element], bar);
// Update element
touch_update_element(&s_scroll_items, element, &s_scroll_items.items->items[element].successes);
}
else if (event->type == TouchEvent_Liftoff) {
// Reset the background
@@ -448,21 +401,9 @@ static void touch_handler(const TouchEvent *event, void *context) {
if (event->type == TouchEvent_Touchdown) {
// Change background to pressed
bitmap_layer_set_bitmap(s_scroll_items.backgrounds[element], s_background_minus_pressed_bitmap);
s_scroll_items.items->items[element].fails++;
int total = s_scroll_items.items->items[element].successes + s_scroll_items.items->items[element].fails;
float percentage = (float)s_scroll_items.items->items[element].successes / total;
GColor color = get_color_float(percentage);
fill_percentage_buffer(&s_scroll_items, element, total, percentage);
text_layer_set_text_color(s_scroll_items.numbers[element], color);
text_layer_set_text(s_scroll_items.numbers[element], s_scroll_items.numbers_buffer[element]);
// Update the percentage bar
int width = (PERCENTAGE_BAR_WIDTH) * percentage;
GRect bar = GRect(31, (element * ITEM_UI_HEIGHT) + 40, width, 4);
GColor *color_ptr = layer_get_data(s_scroll_items.success_bars[element]);
*color_ptr = color;
layer_set_frame(s_scroll_items.success_bars[element], bar);
// Update element
touch_update_element(&s_scroll_items, element, &s_scroll_items.items->items[element].fails);
}
else if (event->type == TouchEvent_Liftoff) {
// Reset the background
@@ -477,9 +418,6 @@ void scrolllayer_init(Layer *parent, Window *window) {
s_scroll_page = 0;
GRect bounds = SCROLLLAYER_FRAME_RECT;
// Load settings
app_settings = settings_get();
// Load custom fonts
s_scrolllayer_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_SLKSCR_16));
s_scrolllayer_font_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_SLKSCR_8));
@@ -549,9 +487,6 @@ void scrolllayer_init(Layer *parent, Window *window) {
}
void scrolllayer_deinit() {
// Destroy settings
app_settings = NULL;
// Unload fonts
fonts_unload_custom_font(s_scrolllayer_font);
fonts_unload_custom_font(s_scrolllayer_font_small);
+19 -23
View File
@@ -5,7 +5,7 @@ module.exports = [
},
{
"type": "text",
"defaultValue": "Add/remove up to 9 items. Character limit is 10. If numbers go higher than 1000, use percentage."
"defaultValue": "Add/remove/update up to 9 items. Name character limit is 40. If more than 10 characters, font goes smaller. If numbers go higher than 1000, use percentage."
},
{
@@ -18,42 +18,24 @@ module.exports = [
{
"type": "input",
"messageKey": "ITEM_NAME",
"label": "Name",
"description": "Non-case sensitive. Use existing name to replace/remove",
"defaultValue": ""
},
{
"type": "input",
"messageKey": "ITEM_SUCCESS",
"label": "Success",
"description": "Set success value. 0 keeps old value if available",
"defaultValue": "0"
},
{
"type": "input",
"messageKey": "ITEM_FAIL",
"label": "Fail",
"description": "Set fail value. 0 keeps old value if available",
"defaultValue": "0"
},
{
"type": "toggle",
"messageKey": "ITEM_PERCENTAGE",
"label": "Show percentage",
"defaultValue": false
},
{
"type": "toggle",
"messageKey": "ITEM_REMOVE",
"label": "Remove item",
"defaultValue": false
}
]
},
{
"type": "section",
"items": [
{
"type": "heading",
"defaultValue": "Settings"
},
{
"type": "slider",
"messageKey": "RED_LIMIT",
@@ -73,6 +55,20 @@ module.exports = [
"min": 1,
"max": 100,
"step": 1
},
{
"type": "toggle",
"messageKey": "ITEM_PERCENTAGE",
"label": "Show percentage",
"description": "Disabled shows success/total. Enabled shows percentage instead",
"defaultValue": false
},
{
"type": "toggle",
"messageKey": "ITEM_REMOVE",
"label": "Remove item",
"description": "Disabled adds/updates item. Enabled removes item",
"defaultValue": false
}
]
},