refactor(layers): layer data API usage

This commit is contained in:
mikhail "synzr" 2025-10-15 17:18:22 +05:00
parent b68a52b4d2
commit 2778dc4eda
7 changed files with 71 additions and 67 deletions

View file

@ -38,14 +38,14 @@
"spaceOptimization": "memory"
}, {
"type": "font",
"name": "CLOCK_FONT_40",
"file": "clock_font_big.ttf",
"characterRange": "[0-9]"
"name": "FONT_TORO_38",
"file": "font_toro.ttf",
"characterRange": "[0-9:]"
}, {
"type": "font",
"name": "CLOCK_FONT_28",
"file": "clock_font_small.ttf",
"characterRange": "[0-9]"
"name": "FONT_KONEKO_TORO_28",
"file": "font_koneko_toro.ttf",
"characterRange": "[0-9/WTFSMedhuriaton]"
}]
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
resources/font_toro.ttf Normal file

Binary file not shown.

View file

@ -3,18 +3,23 @@
#define CHARACTER_H 80
#define CHARACTER_STEP 4
typedef struct CharacterLayerData {
int ticks;
GBitmap *even;
GBitmap *odd;
} CharacterLayerData;
static Layer *s_character_layer;
static GBitmap *s_character_even;
static GBitmap *s_character_odd;
static int s_character_ticks;
static void character_layer_update_proc(Layer *layer, GContext *ctx) {
CharacterLayerData *layer_data = layer_get_data(s_character_layer);
// Get the character bitmap.
GBitmap *bitmap;
if (s_character_ticks % 2 == 0) {
bitmap = s_character_even;
if (layer_data->ticks % 2 == 0) {
bitmap = layer_data->even;
} else {
bitmap = s_character_odd;
bitmap = layer_data->odd;
}
// Get the position of character bitmap and align it to bottom.
@ -23,7 +28,7 @@ static void character_layer_update_proc(Layer *layer, GContext *ctx) {
grect_align(&frame, &frame_inside, GAlignBottom, true);
// Move the character.
switch (s_character_ticks) {
switch (layer_data->ticks) {
case 1:
frame.origin.x += CHARACTER_STEP; // to right
break;
@ -38,30 +43,32 @@ static void character_layer_update_proc(Layer *layer, GContext *ctx) {
}
void character_layer_init(Window *window) {
s_character_ticks = 0;
s_character_even = gbitmap_create_with_resource(RESOURCE_ID_CHARACTER_EVEN);
s_character_odd = gbitmap_create_with_resource(RESOURCE_ID_CHARACTER_ODD);
Layer *window_root_layer = window_get_root_layer(window);
GRect window_bounds = layer_get_unobstructed_bounds(window_root_layer);
s_character_layer =
layer_create(GRect(0, window_bounds.size.h - CHARACTER_H, window_bounds.size.w, CHARACTER_H));
layer_set_update_proc(s_character_layer, character_layer_update_proc);
layer_create_with_data(GRect(0, window_bounds.size.h - CHARACTER_H, window_bounds.size.w, CHARACTER_H), sizeof(CharacterLayerData));
CharacterLayerData *layer_data = layer_get_data(s_character_layer);
layer_data->even = gbitmap_create_with_resource(RESOURCE_ID_CHARACTER_EVEN);
layer_data->odd = gbitmap_create_with_resource(RESOURCE_ID_CHARACTER_ODD);
layer_data->ticks = 0;
layer_set_update_proc(s_character_layer, character_layer_update_proc);
layer_add_child(window_root_layer, s_character_layer);
}
void character_layer_tick(void) {
if (++s_character_ticks == 4) {
s_character_ticks = 0;
CharacterLayerData *layer_data = layer_get_data(s_character_layer);
if (++layer_data->ticks == 4) {
layer_data->ticks = 0;
}
layer_mark_dirty(s_character_layer);
}
void character_layer_deinit(void) {
CharacterLayerData *layer_data = layer_get_data(s_character_layer);
gbitmap_destroy(layer_data->even);
gbitmap_destroy(layer_data->odd);
layer_destroy(s_character_layer);
gbitmap_destroy(s_character_even);
gbitmap_destroy(s_character_odd);
}

View file

@ -1,14 +1,19 @@
#include "clock_layer.h"
#define CLOCK_COMMON_SPACE 2
#define CLOCK_BETWEEN_HM_SPACE 8
#define CLOCK_H 40
#define CLOCK_SPACE 2
#define CLOCK_OFFSET 4
typedef struct ClockLayerData {
GFont font_big;
GFont font_small;
} ClockLayerData;
static GFont s_clock_font_big;
static GFont s_clock_font_small;
static Layer *s_clock_layer;
static char s_clock_measure_buffer[4];
static void clock_layer_update_proc(Layer *layer, GContext *ctx) {
ClockLayerData *layer_data = layer_get_data(s_clock_layer);
// Fill a whole layer with the black color.
GRect layer_bounds = layer_get_unobstructed_bounds(layer);
layer_bounds.origin = GPoint(0, 0);
@ -19,55 +24,46 @@ static void clock_layer_update_proc(Layer *layer, GContext *ctx) {
time_t tmp = time(NULL);
struct tm *time = localtime(&tmp);
// Drawing the measures.
// Drawing the time and seconds.
static char time_text[6], seconds_text[3] = "00\0";
graphics_context_set_text_color(ctx, GColorWhite);
GSize big_text_size = graphics_text_layout_get_content_size(
"00", s_clock_font_big, layer_bounds, GTextOverflowModeFill, GTextAlignmentLeft);
GSize small_text_size = graphics_text_layout_get_content_size(
"00", s_clock_font_small, layer_bounds, GTextOverflowModeFill, GTextAlignmentLeft);
strftime(time_text, sizeof(time_text), clock_is_24h_style() ? "%H:%M" : "%I:%M", time);
GSize time_text_size = graphics_text_layout_get_content_size(
time_text, layer_data->font_big, layer_bounds, GTextOverflowModeFill, GTextAlignmentLeft);
int clock_w =
(big_text_size.w * 2) + small_text_size.w + CLOCK_COMMON_SPACE + CLOCK_BETWEEN_HM_SPACE;
int clock_w_pad = (layer_bounds.size.w - clock_w) / 2;
seconds_text[0] = seconds_text[1] = '0';
GSize seconds_text_size = graphics_text_layout_get_content_size(
seconds_text, layer_data->font_small, layer_bounds, GTextOverflowModeFill, GTextAlignmentLeft);
strftime(seconds_text, sizeof(seconds_text), "%S", time);
strftime(s_clock_measure_buffer, sizeof(s_clock_measure_buffer),
clock_is_24h_style() ? "%H" : "%I", time);
graphics_draw_text(ctx, s_clock_measure_buffer, s_clock_font_big,
GRect(clock_w_pad, 1, big_text_size.w, big_text_size.h),
GTextOverflowModeFill, GTextAlignmentLeft, NULL);
GRect timestamp_rect =
GRect(0, 0, time_text_size.w + seconds_text_size.w + CLOCK_SPACE, time_text_size.h);
grect_align(&timestamp_rect, &layer_bounds, GAlignCenter, true);
timestamp_rect.origin.y -= CLOCK_OFFSET;
strftime(s_clock_measure_buffer, sizeof(s_clock_measure_buffer), "%M", time);
graphics_draw_text(ctx, s_clock_measure_buffer, s_clock_font_big,
GRect(clock_w_pad + big_text_size.w + CLOCK_BETWEEN_HM_SPACE, 1,
big_text_size.w, big_text_size.h),
GTextOverflowModeFill, GTextAlignmentLeft, NULL);
GRect time_rect =
GRect(timestamp_rect.origin.x, timestamp_rect.origin.y, time_text_size.w, time_text_size.h);
graphics_draw_text(ctx, time_text, layer_data->font_big, time_rect, GTextOverflowModeFill,
GTextAlignmentLeft, NULL);
strftime(s_clock_measure_buffer, sizeof(s_clock_measure_buffer), "%S", time);
graphics_draw_text(
ctx, s_clock_measure_buffer, s_clock_font_small,
GRect(clock_w_pad + (big_text_size.w * 2) + CLOCK_BETWEEN_HM_SPACE + CLOCK_COMMON_SPACE,
small_text_size.h - 13, small_text_size.w, small_text_size.h),
GTextOverflowModeFill, GTextAlignmentLeft, NULL);
// Draw the colon between hours and minutes;
graphics_context_set_fill_color(ctx, GColorWhite);
int colon_x = clock_w_pad + big_text_size.w - 2;
graphics_fill_rect(ctx, GRect(colon_x, (big_text_size.h / 4) + 3, 6, 6), 0, GCornerNone);
graphics_fill_rect(ctx, GRect(colon_x, (big_text_size.h / 4) + (big_text_size.h / 2) - 3, 6, 6),
0, GCornerNone);
GRect seconds_rect = GRect(0, 0, seconds_text_size.w, seconds_text_size.h);
grect_align(&seconds_rect, &timestamp_rect, GAlignBottomRight, true);
graphics_draw_text(ctx, seconds_text, layer_data->font_small, seconds_rect, GTextOverflowModeFill,
GTextAlignmentLeft, NULL);
}
void clock_layer_init(Window *window, GPoint position) {
s_clock_font_big = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_CLOCK_FONT_40));
s_clock_font_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_CLOCK_FONT_28));
Layer *window_root_layer = window_get_root_layer(window);
GRect window_bounds = layer_get_unobstructed_bounds(window_root_layer);
s_clock_layer =
layer_create(GRect(position.x, position.y, window_bounds.size.w - position.x, 40));
layer_create_with_data(GRect(position.x, position.y, window_bounds.size.w - position.x, CLOCK_H), sizeof(ClockLayerData));
ClockLayerData *layer_data = layer_get_data(s_clock_layer);
layer_data->font_big = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_TORO_38));
layer_data->font_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_KONEKO_TORO_28));
layer_set_update_proc(s_clock_layer, clock_layer_update_proc);
layer_add_child(window_root_layer, s_clock_layer);
}
@ -77,7 +73,8 @@ void clock_layer_tick(void) {
}
void clock_layer_deinit(void) {
ClockLayerData *layer_data = layer_get_data(s_clock_layer);
fonts_unload_custom_font(layer_data->font_big);
fonts_unload_custom_font(layer_data->font_small);
layer_destroy(s_clock_layer);
fonts_unload_custom_font(s_clock_font_big);
fonts_unload_custom_font(s_clock_font_small);
}