From 65dfb417d32164ff8e085efa2e254c397056738a Mon Sep 17 00:00:00 2001 From: Randall Winkhart Date: Sun, 19 Jul 2026 14:25:40 -0400 Subject: [PATCH] Initial icon animation support --- README.md | 23 ++++++++++++++-- package.json | 5 +--- src/c/neat_bar.c | 70 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 63baedd..e6e1494 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,22 @@ -# neat_bar (WIP - DO NOT USE YET) +# neat_bar +A customizable replacement for the built-in Pebble action bar. -Customizable replacement for the built-in Pebble action bar. +## VS Stock Action Bar +### New Features +- Floating mode +- Rectangular mode on round watches +- Adjustable spread (distance between icons) +- Custom corner radius +- Custom width +- Custom height +- Custom x/y positions +- Legacy Pebble SDK 2.X-style preset +### Removed Features +- Custom animations + - Use built-in presets + - Move up/down/left/right (same as stock) +### Pending Features +- Built-in haptics +- Round-style (currently only rectangular, even on round watches) +- Legacy (background invert) animations support +- Teardown/destroy/deinit helper diff --git a/package.json b/package.json index e7e43c8..7203db3 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,6 @@ "emery", "flint", "gabbro" - ], - "resources": { - "media": [] - } + ] } } diff --git a/src/c/neat_bar.c b/src/c/neat_bar.c index 20fb04c..797739c 100644 --- a/src/c/neat_bar.c +++ b/src/c/neat_bar.c @@ -22,12 +22,70 @@ static const GRect s_base_grect_rect = GRect(PBL_DISPLAY_WIDTH - ACTION_BAR_WIDT static NeatBarLayer *s_current_neat_bar = NULL; -static void s_up_down_handler(ClickRecognizerRef recognizer, void *context) {} -static void s_up_up_handler(ClickRecognizerRef recognizer, void *context) {} -static void s_down_down_handler(ClickRecognizerRef recognizer, void *context) {} -static void s_down_up_handler(ClickRecognizerRef recognizer, void *context) {} -static void s_select_down_handler(ClickRecognizerRef recognizer, void *context) {} -static void s_select_up_handler(ClickRecognizerRef recognizer, void *context) {} +static Animation *s_animate_move(NeatBarLayer *neat_bar, uint8_t button_index, bool move_on_y_axis, int16_t distance) { + BitmapLayer *bitmap_layer = NULL; + + switch (button_index) { + case BUTTON_ID_UP: + bitmap_layer = neat_bar->up_layer; + break; + case BUTTON_ID_SELECT: + bitmap_layer = neat_bar->select_layer; + break; + case BUTTON_ID_DOWN: + bitmap_layer = neat_bar->down_layer; + break; + default: + return NULL; + } + + if (!bitmap_layer) { + return NULL; + } + + Layer *layer = bitmap_layer_get_layer(bitmap_layer); + GRect from_frame = layer_get_frame(layer); + GRect to_frame = from_frame; + if (move_on_y_axis) { + to_frame.origin.y += distance; + } else { + to_frame.origin.x += distance; + } + + PropertyAnimation *prop_anim = property_animation_create_layer_frame(layer, &from_frame, &to_frame); + return property_animation_get_animation(prop_anim); +} + +static void s_icon_down_handler(NeatBarLayer *neat_bar, uint8_t button_index) { + Animation *anim = s_animate_move(neat_bar, button_index, false, -4); + animation_set_duration(anim, 80); + animation_schedule(anim); +} + +static void s_icon_up_handler(NeatBarLayer *neat_bar, uint8_t button_index) { + Animation *anim = s_animate_move(neat_bar, button_index, false, 4); + animation_set_duration(anim, 80); + animation_schedule(anim); +} + +static void s_up_down_handler(ClickRecognizerRef recognizer, void *context) { + s_icon_down_handler(context, BUTTON_ID_UP); +} +static void s_up_up_handler(ClickRecognizerRef recognizer, void *context) { + s_icon_up_handler(context, BUTTON_ID_UP); +} +static void s_down_down_handler(ClickRecognizerRef recognizer, void *context) { + s_icon_down_handler(context, BUTTON_ID_DOWN); +} +static void s_down_up_handler(ClickRecognizerRef recognizer, void *context) { + s_icon_up_handler(context, BUTTON_ID_DOWN); +} +static void s_select_down_handler(ClickRecognizerRef recognizer, void *context) { + s_icon_down_handler(context, BUTTON_ID_SELECT); +} +static void s_select_up_handler(ClickRecognizerRef recognizer, void *context) { + s_icon_up_handler(context, BUTTON_ID_SELECT); +} static void s_main_layer_update_proc(Layer *layer, GContext *ctx) { graphics_context_set_antialiased(ctx, false);