Initial icon animation support

This commit is contained in:
2026-07-19 14:25:40 -04:00
parent e7264a0adb
commit 65dfb417d3
3 changed files with 86 additions and 12 deletions
+21 -2
View File
@@ -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
+1 -4
View File
@@ -16,9 +16,6 @@
"emery",
"flint",
"gabbro"
],
"resources": {
"media": []
}
]
}
}
+64 -6
View File
@@ -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);