Fix ability to permanently move icons with rapid presses

This commit is contained in:
2026-07-19 21:24:34 -04:00
parent 928cf6f2ba
commit d805d2985a
2 changed files with 61 additions and 18 deletions
+58 -18
View File
@@ -36,50 +36,87 @@ static const GRect s_base_grect_rect = GRect(PBL_DISPLAY_WIDTH - ACTION_BAR_WIDT
static NeatBarLayer *s_current_neat_bar = NULL; static NeatBarLayer *s_current_neat_bar = NULL;
static Animation *s_animate_move(NeatBarLayer *neat_bar, uint8_t button_index, bool move_on_y_axis, int16_t distance) { static GRect s_get_home_frame(NeatBarLayer *neat_bar, uint8_t button_index) {
BitmapLayer *bitmap_layer = NULL; int16_t y_offset = neat_bar->main_grect.origin.y;
int8_t spread = neat_bar->spread;
uint16_t width = neat_bar->main_grect.size.w;
switch (button_index) {
case BUTTON_ID_UP:
return GRect(ICON_X_OFFSET, UP_Y - spread - y_offset, width, 25);
case BUTTON_ID_SELECT:
return GRect(ICON_X_OFFSET, SELECT_Y - y_offset, width, 25);
case BUTTON_ID_DOWN:
return GRect(ICON_X_OFFSET, DOWN_Y + spread - y_offset, width, 25);
default:
return GRectZero;
}
}
// Performs a press or release animation for a single button, anchored to its
// home position. Duplicate events (press when already pressed, release when
// already released) are ignored so overlapping animations cannot accumulate
// drift.
static void s_animate_icon(NeatBarLayer *neat_bar, uint8_t button_index, bool is_press) {
BitmapLayer *bitmap_layer;
bool *pressed;
switch (button_index) { switch (button_index) {
case BUTTON_ID_UP: case BUTTON_ID_UP:
bitmap_layer = neat_bar->up_layer; bitmap_layer = neat_bar->up_layer;
pressed = &neat_bar->up_pressed;
break; break;
case BUTTON_ID_SELECT: case BUTTON_ID_SELECT:
bitmap_layer = neat_bar->select_layer; bitmap_layer = neat_bar->select_layer;
pressed = &neat_bar->select_pressed;
break; break;
case BUTTON_ID_DOWN: case BUTTON_ID_DOWN:
bitmap_layer = neat_bar->down_layer; bitmap_layer = neat_bar->down_layer;
pressed = &neat_bar->down_pressed;
break; break;
default: default:
return NULL; return;
} }
if (!bitmap_layer) { if (!bitmap_layer)
return NULL; return;
if (is_press) {
if (*pressed)
return;
*pressed = true;
} else {
if (!*pressed)
return;
*pressed = false;
} }
Layer *layer = bitmap_layer_get_layer(bitmap_layer); Layer *layer = bitmap_layer_get_layer(bitmap_layer);
GRect from_frame = layer_get_frame(layer); GRect home = s_get_home_frame(neat_bar, button_index);
GRect to_frame = from_frame;
if (move_on_y_axis) { // off = home shifted by -distance (the "pressed" position)
to_frame.origin.y += distance; GRect off = home;
int16_t distance = neat_bar->animations_move_distance;
if (neat_bar->animations_move_on_y_axis) {
off.origin.y -= distance;
} else { } else {
to_frame.origin.x += distance; off.origin.x -= distance;
} }
PropertyAnimation *prop_anim = property_animation_create_layer_frame(layer, &from_frame, &to_frame); GRect from = is_press ? home : off;
return property_animation_get_animation(prop_anim); GRect to = is_press ? off : home;
PropertyAnimation *prop_anim = property_animation_create_layer_frame(layer, &from, &to);
Animation *anim = property_animation_get_animation(prop_anim);
animation_set_duration(anim, neat_bar->animations_duration);
animation_schedule(anim);
} }
static void s_icon_down_handler(NeatBarLayer *neat_bar, uint8_t button_index) { static void s_icon_down_handler(NeatBarLayer *neat_bar, uint8_t button_index) {
Animation *anim = s_animate_move(neat_bar, button_index, neat_bar->animations_move_on_y_axis, -neat_bar->animations_move_distance); s_animate_icon(neat_bar, button_index, true);
animation_set_duration(anim, neat_bar->animations_duration);
animation_schedule(anim);
} }
static void s_icon_up_handler(NeatBarLayer *neat_bar, uint8_t button_index) { static void s_icon_up_handler(NeatBarLayer *neat_bar, uint8_t button_index) {
Animation *anim = s_animate_move(neat_bar, button_index, neat_bar->animations_move_on_y_axis, neat_bar->animations_move_distance); s_animate_icon(neat_bar, button_index, false);
animation_set_duration(anim, neat_bar->animations_duration);
animation_schedule(anim);
} }
static void s_up_down_handler(ClickRecognizerRef recognizer, void *context) { static void s_up_down_handler(ClickRecognizerRef recognizer, void *context) {
@@ -332,6 +369,9 @@ NeatBarLayer *neat_bar_layer_create() {
neat_bar->animations_move_on_y_axis = false; neat_bar->animations_move_on_y_axis = false;
neat_bar->animations_move_distance = ANIM_DISTANCE; neat_bar->animations_move_distance = ANIM_DISTANCE;
neat_bar->animations_duration = 144; neat_bar->animations_duration = 144;
neat_bar->up_pressed = false;
neat_bar->select_pressed = false;
neat_bar->down_pressed = false;
neat_bar->context = NULL; neat_bar->context = NULL;
layer_set_update_proc(neat_bar->main_layer, s_main_layer_update_proc); layer_set_update_proc(neat_bar->main_layer, s_main_layer_update_proc);
s_current_neat_bar = neat_bar; s_current_neat_bar = neat_bar;
+3
View File
@@ -21,6 +21,9 @@ typedef struct {
int8_t animations_move_distance; int8_t animations_move_distance;
uint8_t animations_duration; uint8_t animations_duration;
//bool use_legacy_animations //bool use_legacy_animations
bool up_pressed;
bool select_pressed;
bool down_pressed;
void *context; void *context;
} NeatBarLayer; } NeatBarLayer;