void destroy_animations() { //unschedule any previous animation animation_unschedule((Animation*)back_animation_old); animation_unschedule((Animation*)back_animation_new); animation_unschedule((Animation*)card_animation_old); animation_unschedule((Animation*)card_animation_new); animation_unschedule((Animation*)expanded_animation); //destroy memory used for previous animation if(back_animation_old != NULL) property_animation_destroy(back_animation_old); if(back_animation_new != NULL) property_animation_destroy(back_animation_new); if(card_animation_old != NULL) property_animation_destroy(card_animation_old); if(card_animation_new != NULL) property_animation_destroy(card_animation_new); if(expanded_animation != NULL) property_animation_destroy(expanded_animation); //make NULL to avoid redestroying memory back_animation_old = NULL; back_animation_new = NULL; card_animation_old = NULL; card_animation_new = NULL; expanded_animation = NULL; }
void handle_tap(AccelAxisType axis, int32_t direction) { static BatteryChargeState chargeState; int i, s; if (splashEnded && !animRunning) { if (animation_is_scheduled(anim)) { animation_unschedule(anim); } animRunning = true; chargeState = battery_state_service_peek(); s = chargeState.charge_percent; for (i=0; i<NUMSLOTS; i++) { slot[i].prevDigit = slot[i].curDigit; } slot[4].curDigit = 'B' - '0'; slot[5].curDigit = 'A' - '0'; slot[6].curDigit = 'T' - '0'; slot[7].curDigit = SPACE_D; slot[8].curDigit = (s==100)?1:SPACE_D; slot[9].curDigit = (s<100)?s/10:0; slot[10].curDigit = (s<100)?s/100:0; slot[11].curDigit = PERCENT; animation_schedule(anim); app_timer_register(BATTERYDELAY, handle_timer, NULL); } }
void handle_tick(AppContextRef ctx, PebbleTickEvent *evt) { PblTm now; int ho, mi, da, mo, i; if (splashEnded) { if (animation_is_scheduled(&anim)) animation_unschedule(&anim); get_time(&now); ho = get_display_hour(now.tm_hour); mi = now.tm_min; da = now.tm_mday; mo = now.tm_mon+1; for (i=0; i<NUMSLOTS; i++) { slot[i].prevDigit = slot[i].curDigit; } slot[0].curDigit = ho/10; slot[1].curDigit = ho%10; slot[2].curDigit = mi/10; slot[3].curDigit = mi%10; if (US_DATE) { slot[6].curDigit = da/10; slot[7].curDigit = da%10; slot[4].curDigit = mo/10; slot[5].curDigit = mo%10; } else { slot[4].curDigit = da/10; slot[5].curDigit = da%10; slot[6].curDigit = mo/10; slot[7].curDigit = mo%10; } if (NO_ZERO) { if (slot[0].curDigit == 0) { slot[0].curDigit = 10; if (slot[0].prevDigit == 10) { slot[0].curDigit++; } } if (slot[4].curDigit == 0) { slot[4].curDigit = 10; if (slot[4].prevDigit == 10) { slot[4].curDigit++; } } if (slot[6].curDigit == 0) { slot[6].curDigit = 10; if (slot[6].prevDigit == 10) { slot[6].curDigit++; } } } animation_schedule(&anim); } }
void handle_bluetooth(bool connected) { int i; if (lastBluetoothStatus == connected) { return; } else { lastBluetoothStatus = connected; if (splashEnded && !animRunning) { if (animation_is_scheduled(anim)) { animation_unschedule(anim); } animRunning = true; for (i=0; i<NUMSLOTS; i++) { slot[i].prevDigit = slot[i].curDigit; } slot[0].curDigit = 'B' - '0'; slot[1].curDigit = 'T' - '0'; if (connected) { slot[2].curDigit = 'O' - '0'; slot[3].curDigit = 'K' - '0'; slot[4].curDigit = SPACE_D; slot[5].curDigit = SPACE_D; slot[6].curDigit = SPACE_D; slot[7].curDigit = SPACE_D; slot[8].curDigit = SPACE_D; slot[9].curDigit = SPACE_D; slot[10].curDigit = SPACE_D; slot[11].curDigit = SPACE_D; vibes_double_pulse(); } else { slot[2].curDigit = SPACE_L; slot[3].curDigit = SPACE_R; slot[4].curDigit = SPACE_D; slot[5].curDigit = 'F' - '0'; slot[6].curDigit = 'A' - '0'; slot[7].curDigit = 'I' - '0'; slot[8].curDigit = 'L' - '0'; slot[9].curDigit = 'E' - '0'; slot[10].curDigit = 'D' - '0'; slot[11].curDigit = SPACE_D; vibes_long_pulse(); } animation_schedule(anim); app_timer_register(BATTERYDELAY, handle_timer, NULL); } } }
void destroy_property_animation(PropertyAnimation **animation) { if (*animation == NULL) return; if (animation_is_scheduled((Animation*) *animation)) animation_unschedule((Animation*) *animation); // can happen if there is a stop handler which destroys the animation if (*animation == NULL) return; property_animation_destroy(*animation); *animation = NULL; }
void destroy_property_animation(PropertyAnimation **prop_animation) { if (*prop_animation == NULL) { return; } if (animation_is_scheduled((Animation*) *prop_animation)) { animation_unschedule((Animation*) *prop_animation); } property_animation_destroy(*prop_animation); *prop_animation = NULL; }
/* segment_show draws a segment with an animation */ void segment_show(Quadrant *quadrant, int id) { GRect visible = Segments[id].visible; GRect invisible = Segments[id].invisible; /* Ensures the segment is not animating to prevent bugs */ if(animation_is_scheduled(&quadrant->animations[id].animation)) { animation_unschedule(&quadrant->animations[id].animation); } property_animation_init_layer_frame(&quadrant->animations[id], &quadrant->segments[id], &invisible, &visible); animation_set_duration(&quadrant->animations[id].animation, AnimationTime); animation_set_curve(&quadrant->animations[id].animation, AnimationCurveLinear); animation_schedule(&quadrant->animations[id].animation); }
static void animate_layer_bounds(Layer* layer, GRect toRect) { if(!animation_finished) { //APP_LOG(APP_LOG_LEVEL_DEBUG,"in cleanup..."); animation_unschedule((Animation*)animation); //property_animation_destroy(animation); animation_finished=true; layer_set_frame(text_layer_get_layer(description_layer),GRect(0, TEXT_OFFSET_Y, 5*SCREEN_WIDTH, 24)); } animation = property_animation_create_layer_frame(layer, NULL, &toRect); animation_set_handlers((Animation*) animation, (AnimationHandlers) { .stopped = (AnimationStoppedHandler) animation_stopped, }, NULL);
static void animate_hub_layer(GRect start, GRect finish) { if (animation_is_ongoing) { #ifdef PBL_SDK_2 animation_unschedule((Animation*)prop_anim); if (prop_anim) property_animation_destroy(prop_anim); prop_anim = NULL; #endif } animation_is_ongoing = true; prop_anim = property_animation_create_layer_frame(hub_layer, &start, &finish); animation_set_duration((Animation*)prop_anim, 1000); animation_set_handlers((Animation*)prop_anim, (AnimationHandlers) { .stopped = anim_stopped_handler }, NULL);
void handle_tap(AccelAxisType axis, int32_t direction) { static BatteryChargeState chargeState; int i, s; if (splashEnded) { if (showBattery) { showBattery = false; app_timer_cancel(timerBattery); handle_timer(NULL); } else { if (animation_is_scheduled(anim)) { animation_unschedule(anim); } for (i=0; i<NUMSLOTS; i++) { slot[i].prevDigit = slot[i].curDigit; } chargeState = battery_state_service_peek(); s = chargeState.charge_percent / 10; if (s<1) { s = 1; } else if (s>9) { s = 9; } s--; //for (i=0; i<4; i++) { // slot[i].curDigit = BATTERYOFFSET + 4*s + i; //} slot[4].curDigit = 'B' - '0'; slot[5].curDigit = 'A' - '0'; slot[6].curDigit = 'T' - '0'; slot[7].curDigit = 'T' - '0'; slot[8].curDigit = SPACE_D; slot[9].curDigit = s+1; slot[10].curDigit = 0; slot[11].curDigit = PERCENT; showBattery = true; animation_schedule(anim); timerBattery = app_timer_register(BATTERYDELAY, handle_timer, NULL); } } }
void prv_back_click_handler(ClickRecognizerRef recognizer, void *context) { Layer *layer = (Layer*)context; SelectionLayerData *data = layer_get_data(layer); if (data->is_active) { animation_unschedule(data->next_cell_animation); if (data->selected_cell_idx == 0) { data->selected_cell_idx = 0; window_stack_pop(true); } else { data->slide_is_forward = false; prv_run_slide_animation(layer); } } }
void animation_schedule(struct Animation *animation) { if (animation->implementation==0) return; if (animation_is_scheduled(animation)) animation_unschedule(animation); animation->is_completed=true; //Yes this is meant to be true! That is how the engine determines if a animation is in "delay" state animation->abs_start_time_ms=SDL_GetTicks(); animation->list_node.next=(ListNode*)firstScheduledAnimation; animation->list_node.prev=0; if (firstScheduledAnimation!=0) firstScheduledAnimation->list_node.prev=(ListNode*)animation; firstScheduledAnimation=animation; if (animation->implementation->setup!=0) animation->implementation->setup (animation); }
void prv_select_click_handler(ClickRecognizerRef recognizer, void *context) { Layer *layer = (Layer*)context; SelectionLayerData *data = layer_get_data(layer); if (data->is_active) { animation_unschedule(data->next_cell_animation); if (data->selected_cell_idx >= data->num_cells - 1) { data->selected_cell_idx = 0; data->callbacks.complete(data->context); } else { data->slide_is_forward = true; prv_run_slide_animation(layer); } } }
static void animation_update(struct Animation *animation, const AnimationProgress time_normalized) { SlidingTextData *data = s_data; struct SlidingTextRenderState *rs = &data->render_state; time_t now = time(NULL); struct tm t = *localtime(&now); bool something_changed = false; if (data->last_minute != t.tm_min) { something_changed = true; minute_to_formal_words(t.tm_min, rs->first_minutes[rs->next_minutes], rs->second_minutes[rs->next_minutes]); if(data->last_hour != t.tm_hour || t.tm_min <= 20 || t.tm_min/10 != data->last_minute/10) { slide_in_text(data, &data->rows[1], rs->first_minutes[rs->next_minutes]); } else { // The tens line didn't change, so swap to the correct buffer but don't animate text_layer_set_text(data->rows[1].label, rs->first_minutes[rs->next_minutes]); } slide_in_text(data, &data->rows[2], rs->second_minutes[rs->next_minutes]); rs->next_minutes = rs->next_minutes ? 0 : 1; data->last_minute = t.tm_min; } if (data->last_hour != t.tm_hour) { hour_to_12h_word(t.tm_hour, rs->hours[rs->next_hours]); slide_in_text(data, &data->rows[0], rs->hours[rs->next_hours]); rs->next_hours = rs->next_hours ? 0 : 1; data->last_hour = t.tm_hour; } for (size_t i = 0; i < ARRAY_LENGTH(data->rows); ++i) { something_changed = update_sliding_row(data, &data->rows[i]) || something_changed; } if (!something_changed) { animation_unschedule(data->animation); } }
void hide_expanded_down_press() { animation_unschedule((Animation*)expanded_animation); //destroy memory used for previous animation if(expanded_animation != NULL) property_animation_destroy(expanded_animation); //make NULL to avoid redestroying memory expanded_animation = NULL; GRect expanded_from = GRect(0,EXPAND_SIZE, 144, 168-EXPAND_SIZE); GRect expanded_to = GRect(0, 0-(168-EXPAND_SIZE), 144, 168-EXPAND_SIZE); //animate expanded layer expanded_animation = property_animation_create_layer_frame(expanded_layer, &expanded_from, &expanded_to); animation_set_curve((Animation*) expanded_animation, AnimationCurveEaseOut); animation_set_duration((Animation*) expanded_animation, 300); animation_schedule((Animation*) expanded_animation); expanded_visible = 0; }
void service_animations () { Animation* cursor=firstScheduledAnimation,* tempCursor; bool isDirty=false; uint32_t time=0; while (cursor!=0) { if (cursor->is_completed) { //"delay" state if (SDL_GetTicks()-cursor->abs_start_time_ms>=cursor->delay_ms) { cursor->abs_start_time_ms=SDL_GetTicks(); cursor->is_completed=false; if (cursor->handlers.started!=0) cursor->handlers.started(cursor,cursor->context); } } else { if (cursor->duration_ms==ANIMATION_DURATION_INFINITE) time=ANIMATION_DURATION_INFINITE; else if (SDL_GetTicks()-cursor->abs_start_time_ms>=cursor->duration_ms) { //the simulator runs on 60 fps. to ensure the maximal value is reached, this has to be done cursor->implementation->update (cursor,ANIMATION_NORMALIZED_MAX); isDirty=true; cursor->is_completed=true; tempCursor=cursor; cursor=(Animation*)cursor->list_node.next; animation_unschedule(tempCursor); continue; } else time=(ANIMATION_NORMALIZED_MIN + (((ANIMATION_NORMALIZED_MAX - ANIMATION_NORMALIZED_MIN) * (SDL_GetTicks()-cursor->abs_start_time_ms)) / cursor->duration_ms)); cursor->implementation->update (cursor,time); isDirty=true; } cursor=(Animation*)cursor->list_node.next; } if (isDirty==true) markDirty (true); }
void handle_bluetooth(bool connected) { int i; if (lastBluetoothStatus == connected) { return; } else { lastBluetoothStatus = connected; if (bluetoothStatus && splashEnded && !animRunning) { if (animation_is_scheduled(anim)) { animation_unschedule(anim); } animRunning = true; for (i=0; i<NUMSLOTS; i++) { slot[i].prevDigit = slot[i].curDigit; } slot[0].curDigit = 'B' - '0'; slot[1].curDigit = 'T' - '0'; if (connected) { slot[2].curDigit = 'O' - '0'; slot[3].curDigit = 'K' - '0'; slot[4].curDigit = SPACE_D; slot[5].curDigit = SPACE_D; slot[6].curDigit = SPACE_D; slot[7].curDigit = SPACE_D; slot[8].curDigit = SPACE_D; slot[9].curDigit = SPACE_D; slot[10].curDigit = SPACE_D; slot[11].curDigit = SPACE_D; vibes_double_pulse(); } else { static const uint32_t segments[] = {80, 30, 80, 30, 80}; VibePattern pat = { .durations = segments, .num_segments = ARRAY_LENGTH(segments), }; slot[2].curDigit = SPACE_L; slot[3].curDigit = SPACE_R; slot[4].curDigit = SPACE_D; slot[5].curDigit = 'F' - '0'; slot[6].curDigit = 'A' - '0'; slot[7].curDigit = 'I' - '0'; slot[8].curDigit = 'L' - '0'; slot[9].curDigit = 'E' - '0'; slot[10].curDigit = 'D' - '0'; slot[11].curDigit = SPACE_D; vibes_enqueue_custom_pattern(pat); } createAnim(); animation_schedule(anim); if (timer==NULL) timer=app_timer_register(BATTERYDELAY, handle_timer, NULL); } } }
void animation_unschedule_all(void) { while (firstScheduledAnimation!=0) animation_unschedule(firstScheduledAnimation); }
void animation_destroy (struct Animation* animation) { if (animation_is_scheduled(animation)) animation_unschedule(animation); if (animation) free(animation); }
void property_animation_destroy (struct PropertyAnimation* animation) { if (animation_is_scheduled((Animation*)animation)) animation_unschedule((Animation*)animation); if (animation) free(animation); }
void handle_tick(struct tm *now, TimeUnits units_changed) { int h, m; int D, M; int i; int wd; int Y; //APP_LOG(APP_LOG_LEVEL_DEBUG, "Entering handle_tick"); if (splashEnded) { if (animation_is_scheduled(anim)) animation_unschedule(anim); h = now->tm_hour; m = now->tm_min; D = now->tm_mday; M = now->tm_mon+1; if (showWeekday) { wd = now->tm_wday; } else { Y = now->tm_year%100; } if (clock_12) { h = h%12; if (h == 0) { h = 12; } } for (i=0; i<NUMSLOTS; i++) { slot[i].prevDigit = slot[i].curDigit; } // Hour slots slot[0].curDigit = h/10; slot[1].curDigit = h%10; slot[2].curDigit = m/10; slot[3].curDigit = m%10; slot[6].curDigit = SPACE_L; slot[9].curDigit = SPACE_R; // Date slots if (showWeekday && USDate) { slot[4].curDigit = weekDay[curLang][wd][0] - '0'; slot[5].curDigit = weekDay[curLang][wd][1] - '0'; slot[7].curDigit = M/10; slot[8].curDigit = M%10; slot[10].curDigit = D/10; slot[11].curDigit = D%10; } else if (showWeekday && !USDate) { slot[4].curDigit = weekDay[curLang][wd][0] - '0'; slot[5].curDigit = weekDay[curLang][wd][1] - '0'; slot[7].curDigit = D/10; slot[8].curDigit = D%10; slot[10].curDigit = M/10; slot[11].curDigit = M%10; } else if (!showWeekday && USDate) { slot[4].curDigit = M/10; slot[5].curDigit = M%10; slot[7].curDigit = D/10; slot[8].curDigit = D%10; slot[10].curDigit = Y/10; slot[11].curDigit = Y%10; } else { slot[4].curDigit = D/10; slot[5].curDigit = D%10; slot[7].curDigit = M/10; slot[8].curDigit = M%10; slot[10].curDigit = Y/10; slot[11].curDigit = Y%10; } animation_schedule(anim); } }