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; }
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); } } }
/* 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); }
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 handle_tick(struct tm *now, TimeUnits units_changed) { int h, m; int D, M; int i; int wd = 0; int Y = 0; //APP_LOG(APP_LOG_LEVEL_DEBUG, "Entering handle_tick"); /* if (splashEnded) { if (animation_is_scheduled(anim)) animation_unschedule(anim); */ if (splashEnded && !animation_is_scheduled(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_is_24h_style()) { 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_D; slot[9].curDigit = SPACE_D; // 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); } }
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_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 setField(int i /* Field Index */, bool negNum, char* value) { static PropertyAnimation *pa1[6] = {NULL}, *pa2[6] = {NULL}; //Arrays to cope with 6 fields { static GSize textContent; static GRect gfrom, gto, gframe; TextLayer *flm = s_data_layer[screens[currentScreen].field_layer_map[i]]; text_layer_set_text_alignment(flm, GTextAlignmentLeft); text_layer_set_text(flm, value); // This line only textContent = text_layer_get_content_size(flm); gfrom = layer_get_bounds((Layer *)flm); gframe = layer_get_frame((Layer *)flm); // APP_LOG(APP_LOG_LEVEL_INFO, "gframe.size.w=%d textContent.w=%d i=%d", gframe.size.w, textContent.w, i); if (textContent.w > gframe.size.w) // Overflowed { // APP_LOG(APP_LOG_LEVEL_INFO, "setfield11 value=%s", value); if ( (pa1[i] == NULL || !animation_is_scheduled((Animation*)pa1[i])) && (pa2[i] == NULL || !animation_is_scheduled((Animation*) pa2[i]))) // We are not already animating { // APP_LOG(APP_LOG_LEVEL_INFO, "setField 10"); gto = gfrom; gfrom.origin.x = 0; gto.origin.x = (gframe.size.w - textContent.w)/2; //Work out har far left to move animate the text // APP_LOG(APP_LOG_LEVEL_INFO, "setField11 gfrom.x=%d gfrom.y=%d", gfrom.origin.x, gfrom.origin.y); // APP_LOG(APP_LOG_LEVEL_INFO, "setField11 gto.x=%d gto.y=%d", gto.origin.x, gto.origin.y); int tim = (int)(-2000.0 * ((float)gto.origin.x) / 20.0); animate_layer_bounds(&pa1[i], (Layer *)flm, &gfrom, >o, tim, 0); animate_layer_bounds(&pa2[i], (Layer *)flm, >o, &gfrom, tim, tim); } else { //APP_LOG(APP_LOG_LEVEL_INFO, "Already scheduled screen=%d i=%d %d %d %d %d", currentScreen, i, (int)pa1[i], animation_is_scheduled((Animation*)pa1[i]), (int)pa2[i], animation_is_scheduled((Animation*)pa2[i]) ); text_layer_set_text(flm, value); // Animation running - just set the text } } else // We need to redraw the text centred in the reset bounds { // APP_LOG(APP_LOG_LEVEL_INFO, "setfield11 value=%s", value); GRect bF = layer_get_bounds((Layer *)flm); GRect fF = layer_get_frame((Layer *)flm); if (bF.size.w != fF.size.w) // is there extra space? { bF.origin.x = -(bF.size.w / 2 - fF.size.w / 2) /2; // APP_LOG(APP_LOG_LEVEL_INFO, "origin.x =%d", bF.origin.x); layer_set_bounds((Layer *)flm, bF); // Centre the Bounds below the Frame } text_layer_set_text_alignment(flm, GTextAlignmentCenter); //Should be Center but need to work out how! text_layer_set_text(flm, value); // This line only } } if (negNum) // Did we get a negative number { doDataInvert(i); } else // No, positive number { doDataRevert(i); } }