Fix ability to permanently move icons with rapid presses
This commit is contained in:
+58
-18
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user