static void ppspinner_update(Layer *layer, GContext *g) { PPSpinnerData *data = (PPSpinnerData *)layer_get_data(layer); GRect bounds = layer_get_frame(layer); // cache some values on stack int frame_number = data->current_frame; int corner_radius = data->corner_radius; int segments = data->segments; // # w = width of segment # g = width of gap # z = ratio of width to gap # s = segments // # we know w, s, z # we want to find w, g // all_width = w s + g (s-1) // g = w z // all_width = w s + (w z)(s-1) // w = all_width / (s z + s - z) float gap_to_piece_ratio = 0.25; int piece_width = (bounds.size.w + 0.0) / (segments * gap_to_piece_ratio + segments - gap_to_piece_ratio); int piece_gap = piece_width * gap_to_piece_ratio; int piece_height = bounds.size.h; graphics_context_set_stroke_color(g, GColorBlack); graphics_context_set_fill_color(g, GColorBlack); for (int i = 0, x = 0; i < segments; i++, x += piece_width + piece_gap) { GRect piece_frame = GRect(x, 0, piece_width, piece_height); graphics_draw_round_rect(g, piece_frame, corner_radius); if (frame_number % segments == i) { graphics_fill_rect(g, piece_frame, corner_radius, GCornersAll); } } }
static void prv_draw_slider_settle(Layer *layer, GContext *ctx) { SelectionLayerData *data = layer_get_data(layer); int starting_x_offset = 0; for (int i = 0; i < data->num_cells; i++) { if (data->selected_cell_idx == i) { break; } starting_x_offset += data->cell_widths[i] + data->cell_padding; } int x_offset = starting_x_offset; if (data->slide_is_forward) { x_offset += data->cell_widths[data->selected_cell_idx]; } int current_width = (data->cell_padding * data->slide_settle_anim_progress) / 100; if (!data->slide_is_forward) { x_offset -= current_width; } GRect rect = GRect(x_offset, 0, current_width, layer_get_bounds(layer).size.h); graphics_context_set_fill_color(ctx, data->active_background_color); graphics_fill_rect(ctx, rect, 1, GCornerNone); }
static void update_arc(Layer *arc_layer, float p) { Arc *arc_ctx = (Arc*) layer_get_data(arc_layer); float old_p = arc_ctx->percent; arc_ctx->percent = p; if (p != old_p) layer_mark_dirty(arc_layer); }
WeatherLayer *weather_layer_create(GRect frame) { // Create a new layer with some extra space to save our custom Layer infos WeatherLayer *weather_layer = layer_create_with_data(frame, sizeof(WeatherLayerData)); WeatherLayerData *wld = layer_get_data(weather_layer); large_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FUTURA_40)); small_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FUTURA_35)); // Add background layer wld->temp_layer_background = text_layer_create(GRect(0, 10, 144, 68)); text_layer_set_background_color(wld->temp_layer_background, GColorWhite); layer_add_child(weather_layer, text_layer_get_layer(wld->temp_layer_background)); // Add temperature layer wld->temp_layer = text_layer_create(GRect(70, 19, 72, 80)); text_layer_set_background_color(wld->temp_layer, GColorClear); text_layer_set_text_alignment(wld->temp_layer, GTextAlignmentCenter); text_layer_set_font(wld->temp_layer, large_font); layer_add_child(weather_layer, text_layer_get_layer(wld->temp_layer)); // Add bitmap layer wld->icon_layer = bitmap_layer_create(GRect(9, 13, 60, 60)); layer_add_child(weather_layer, bitmap_layer_get_layer(wld->icon_layer)); wld->icon = NULL; return weather_layer; }
void weather_animate(void *context) { WeatherData *weather_data = (WeatherData*) context; WeatherLayerData *wld = layer_get_data(weather_layer); if (weather_data->updated == 0 && weather_data->error == WEATHER_E_OK) { animation_step = (animation_step % 3) + 1; layer_mark_dirty(wld->loading_layer); weather_animation_timer = app_timer_register(WEATHER_ANIMATION_REFRESH, weather_animate, weather_data); if (animation_step == WEATHER_INITIAL_RETRY_TIMEOUT) { // Fire off one last desperate attempt... request_weather(weather_data); } if (animation_step > WEATHER_ANIMATION_TIMEOUT) { weather_data->error = WEATHER_E_NETWORK; } } else if (weather_data->error != WEATHER_E_OK) { animation_step = 0; layer_set_hidden(wld->loading_layer, true); weather_layer_set_error(); } }
ScrollLayer* scroll_layer_create(GRect frame) { Layer* layer=layer_create_with_data(frame,sizeof(ScrollLayerData)); if (!layer) return 0; ScrollLayerData* scroll=(ScrollLayerData*)layer_get_data(layer); scroll->content_sublayer=layer_create ((GRect){{0,0},frame.size}); if (!scroll->content_sublayer) { free(layer); return 0; } scroll->shadow_sublayer=layer_create ((GRect){{0,0},frame.size}); if (!scroll->shadow_sublayer) { free(scroll->content_sublayer); free(layer); return 0; } scroll->animation=0; layer_set_update_proc(scroll->shadow_sublayer,scroll_layer_shadow_layer_update_func); layer_add_child (layer,scroll->content_sublayer); layer_add_child (layer,scroll->shadow_sublayer); scroll->callbacks.click_config_provider=0; scroll->callbacks.content_offset_changed_handler=0; scroll->context=0; return (ScrollLayer*)layer; }
static void weather_layer_set_error() { WeatherLayerData *wld = layer_get_data(weather_layer); layer_set_frame(bitmap_layer_get_layer(wld->primary_icon_layer), PRIMARY_ICON_ERROR_FRAME); weather_layer_set_icon(W_ICON_PHONE_ERROR, AREA_PRIMARY); }
void dim_layer_set_dim_mode(DimLayer *dim_layer, DimMode dim_mode) { DimLayerData* data = layer_get_data(dim_layer); data->dim_mode = dim_mode; layer_mark_dirty(dim_layer); }
static void intialise_cylinder_layer(Layer *layer) { APP_LOG(APP_LOG_LEVEL_DEBUG, "intialise_cylinder_layer(%p)", (void*)layer); CylinderState* state = layer_get_data(layer); initialise_cylinder_state(state); layer_set_update_proc(layer, cylinder_layer_update_proc); }
void weather_layer_set_temperature(WeatherLayer* weather_layer, int16_t t, bool is_stale) { WeatherLayerData *wld = layer_get_data(weather_layer); snprintf(wld->temp_str, sizeof(wld->temp_str), "%i%s", t, is_stale ? " " : "°"); // Temperature between -9° -> 9° or 20° -> 99° if ((t >= -9 && t <= 9) || (t >= 20 && t < 100)) { text_layer_set_font(wld->temp_layer, large_font); text_layer_set_text_alignment(wld->temp_layer, GTextAlignmentCenter); // Is the temperature below zero? if (wld->temp_str[0] == '-') { memmove( wld->temp_str + 1 + 1, wld->temp_str + 1, 5 - (1 + 1) ); memcpy(&wld->temp_str[1], " ", 1); } } // Temperature between 10° -> 19° else if (t >= 10 && t < 20) { text_layer_set_font(wld->temp_layer, large_font); text_layer_set_text_alignment(wld->temp_layer, GTextAlignmentLeft); } // Temperature above 99° or below -9° else { text_layer_set_font(wld->temp_layer, small_font); text_layer_set_text_alignment(wld->temp_layer, GTextAlignmentCenter); } text_layer_set_text(wld->temp_layer, wld->temp_str); }
static void prv_draw_text(Layer *layer, GContext *ctx) { SelectionLayerData *data = layer_get_data(layer); for (int i = 0, current_x_offset = 0; i < data->num_cells; i++) { if (data->callbacks.get_cell_text) { char *text = data->callbacks.get_cell_text(i, data->context); if (text) { int height = layer_get_bounds(layer).size.h; if (data->selected_cell_idx == i) { height += prv_get_pixels_for_bump_settle(data->bump_settle_anim_progress); } int y_offset = prv_get_y_offset_which_vertically_centers_font(data->font, height); if (data->selected_cell_idx == i && data->bump_is_upwards) { y_offset -= prv_get_pixels_for_bump_settle(data->bump_settle_anim_progress); } if (data->selected_cell_idx == i) { int delta = (data->bump_text_anim_progress * prv_get_font_top_padding(data->font)) / 100; if (data->bump_is_upwards) { delta *= -1; } y_offset += delta; } GRect rect = GRect(current_x_offset, y_offset, data->cell_widths[i], height); graphics_draw_text(ctx, text, data->font, rect, GTextOverflowModeFill, GTextAlignmentCenter, NULL); } } current_x_offset += data->cell_widths[i] + data->cell_padding; } }
void marquee_text_layer_mark_dirty(MarqueeTextLayer *marquee) { MarqueeData *marqueedata = (MarqueeData *)layer_get_data(marquee); marqueedata->text_width = -1; marqueedata->offset = 0; marqueedata->countdown = 100; layer_mark_dirty(marquee); }
static void prv_draw_cell_backgrounds(Layer *layer, GContext *ctx) { SelectionLayerData *data = layer_get_data(layer); // Loop over each cell and draw the background rectangles for (int i = 0, current_x_offset = 0; i < data->num_cells; i++) { if (data->cell_widths[i] == 0) { continue; } int y_offset = 0; if (data->selected_cell_idx == i && data->bump_is_upwards) { y_offset = -prv_get_pixels_for_bump_settle(data->bump_settle_anim_progress); } int height = layer_get_bounds(layer).size.h; if (data->selected_cell_idx == i) { height += prv_get_pixels_for_bump_settle(data->bump_settle_anim_progress); } const GRect rect = GRect(current_x_offset, y_offset, data->cell_widths[i], height); GColor bg_color = data->inactive_background_color; if (data->selected_cell_idx == i && !data->slide_amin_progress) { bg_color = data->active_background_color; } graphics_context_set_fill_color(ctx, bg_color); graphics_fill_rect(ctx, rect, 1, GCornerNone); current_x_offset += data->cell_widths[i] + data->cell_padding; } }
void selection_layer_set_active_bg_color(Layer *layer, GColor color) { SelectionLayerData *data = layer_get_data(layer); if (data) { data->active_background_color = color; } }
void selection_layer_set_cell_padding(Layer *layer, int padding) { SelectionLayerData *data = layer_get_data(layer); if (data) { data->cell_padding = padding; } }
void selection_layer_set_cell_width(Layer *layer, int idx, int width) { SelectionLayerData *data = layer_get_data(layer); if (data && idx < data->num_cells) { data->cell_widths[idx] = width; } }
void selection_layer_set_font(Layer *layer, GFont font) { SelectionLayerData *data = layer_get_data(layer); if (data) { data->font = font; } }
static void prv_slide_settle_stopped(Animation *animation, bool finished, void *context) { Layer *layer = (Layer*) animation_get_context(animation); SelectionLayerData *data = layer_get_data(layer); data->slide_settle_anim_progress = 0; animation_destroy(animation); }
static void update(Layer* layer, GContext* ctx) { QRData* qr_data = (QRData*) layer_get_data(layer); if (qr_data->width == 0) { return; } uint8_t byte = 0; uint8_t bit = 7; GRect layer_size = layer_get_bounds(layer); uint8_t block_size = layer_size.size.w / qr_data->width; uint8_t padding_x = (layer_size.size.w - (block_size * qr_data->width)) / 2; uint8_t padding_y = (layer_size.size.h - (block_size * qr_data->width)) / 2; for (uint8_t y = 0; y < qr_data->width; y += 1) { for (uint8_t x = 0; x < qr_data->width; x += 1) { bool value = (*((unsigned char*)qr_data->str + byte)) & (1 << bit); if (value) { graphics_fill_rect(ctx, GRect(padding_x + x * block_size, padding_y + y * block_size, block_size, block_size), 0, GCornerNone); } if (bit <= 0) { bit = 7; ++byte; } else { bit -= 1; } } } }
static void prv_slide_settle_impl(struct Animation *animation, const AnimationProgress distance_normalized) { Layer *layer = (Layer*)animation_get_context(animation); SelectionLayerData *data = layer_get_data(layer); data->slide_settle_anim_progress = 100 - ((100 * distance_normalized) / ANIMATION_NORMALIZED_MAX); layer_mark_dirty(layer); }
void console_layer_clear(Layer *console_layer) { console_data_struct *console_data = (console_data_struct*)layer_get_data(console_layer); console_data->pos = 0; console_data->buffer[0] = 0; console_data->buffer[1] = 0; MARK_DIRTY; }
static void inbox_received_callback(DictionaryIterator *iterator, void *context) { uint32_t *layer_data; Tuple *t = dict_read_first(iterator); while(t != NULL) { switch(t->key) { case MSG_KEY_TITLE: strncpy(s_title, t->value->cstring, sizeof(s_title)); text_layer_set_text(s_txt_title, s_title); break; case MSG_KEY_ARTIST: strncpy(s_artist, t->value->cstring, sizeof(s_artist)); text_layer_set_text(s_txt_artist, s_artist); break; case MSG_KEY_VOLUME: layer_data = (uint32_t *)layer_get_data(s_lyr_volume); *layer_data = t->value->int32; layer_mark_dirty(s_lyr_volume); break; case MSG_KEY_PLAY_STATE: if (t->value->int32 > 0) { action_bar_layer_set_icon(s_action_bar, BUTTON_ID_SELECT, s_icon_pause); } else { action_bar_layer_set_icon(s_action_bar, BUTTON_ID_SELECT, s_icon_play); } break; } t = dict_read_next(iterator); } }
void loading_layer_set_text(LoadingLayer* layer, char* text) { LoadingData* data = (LoadingData*)layer_get_data(layer); free_safe(data->message); data->message = malloc(strlen(text) + 1); strcpy(data->message, text); layer_mark_dirty(layer); }
static Layer* selection_layer_init(SelectionLayerData *selection_layer_, GRect frame, int num_cells) { Layer *layer = layer_create_with_data(frame, sizeof(SelectionLayerData)); SelectionLayerData *selection_layer_data = layer_get_data(layer); if (num_cells > MAX_SELECTION_LAYER_CELLS) { num_cells = MAX_SELECTION_LAYER_CELLS; } // Set layer defaults *selection_layer_data = (SelectionLayerData) { .active_background_color = DEFAULT_ACTIVE_COLOR, .inactive_background_color = DEFAULT_INACTIVE_COLOR, .num_cells = num_cells, .cell_padding = DEFAULT_CELL_PADDING, .selected_cell_idx = DEFAULT_SELECTED_INDEX, .font = fonts_get_system_font(DEFAULT_FONT), .is_active = true, }; for (int i = 0; i < num_cells; i++) { selection_layer_data->cell_widths[i] = 0; } layer_set_frame(layer, frame); layer_set_clips(layer, false); layer_set_update_proc(layer, (LayerUpdateProc)prv_draw_selection_layer); return layer; } Layer* selection_layer_create(GRect frame, int num_cells) { SelectionLayerData *selection_layer_data = NULL; return selection_layer_init(selection_layer_data, frame, num_cells); }
void selection_layer_destroy(Layer* layer) { SelectionLayerData *data = layer_get_data(layer); animation_unschedule_all(); if (data) { selection_layer_deinit(layer); } }
static void lyr_volume_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); uint32_t *len = (uint32_t *) layer_get_data(s_lyr_volume); graphics_context_set_fill_color(ctx, GColorWhite); GRect rect = GRect(0, 1, *len, bounds.size.h - 2); graphics_fill_rect(ctx, rect, 1, GCornersAll); }
static void prv_run_slide_animation(Layer *layer) { SelectionLayerData *data = layer_get_data(layer); Animation *over_animation = prv_create_slide_animation(layer); Animation *settle_animation = prv_create_slide_settle_animation(layer); data->next_cell_animation = animation_sequence_create(over_animation, settle_animation, NULL); animation_schedule(data->next_cell_animation); }
static void prv_run_value_change_animation(Layer *layer) { SelectionLayerData *data = layer_get_data(layer); Animation *bump_text = prv_create_bump_text_animation(layer); Animation *bump_settle = prv_create_bump_settle_animation(layer); data->value_change_animation = animation_sequence_create(bump_text, bump_settle, NULL); animation_schedule(data->value_change_animation); }
void ppspinner_start(PPSpinnerLayer *layer) { PPSpinnerData *data = (PPSpinnerData *)layer_get_data(layer); if (data->timer != NULL) { APP_LOG(APP_LOG_LEVEL_WARNING, "Already running"); } else { data->timer = app_timer_register(data->update_ms, ppspinner_handle_timer, layer); } }
static void selection_layer_deinit(Layer* layer) { #ifndef PBL_COLOR SelectionLayerData *data = layer_get_data(layer); inverter_layer_destroy(data->inverter); #endif layer_destroy(layer); }