feat(layers): information layer
This commit is contained in:
parent
1e600be872
commit
48f336a2eb
12 changed files with 205 additions and 3 deletions
27
package.json
27
package.json
|
|
@ -23,6 +23,9 @@
|
|||
"messageKeys": [
|
||||
"dummy"
|
||||
],
|
||||
"capabilities": [
|
||||
"health"
|
||||
],
|
||||
"resources": {
|
||||
"media": [{
|
||||
"type": "bitmap",
|
||||
|
|
@ -36,6 +39,30 @@
|
|||
"file": "character_odd.png",
|
||||
"memoryFormat": "Smallest",
|
||||
"spaceOptimization": "memory"
|
||||
}, {
|
||||
"type": "bitmap",
|
||||
"name": "ICON_BATTERY_EMPTY",
|
||||
"file": "icon_battery_empty.png",
|
||||
"memoryFormat": "Smallest",
|
||||
"spaceOptimization": "memory"
|
||||
}, {
|
||||
"type": "bitmap",
|
||||
"name": "ICON_BATTERY_HALF",
|
||||
"file": "icon_battery_half.png",
|
||||
"memoryFormat": "Smallest",
|
||||
"spaceOptimization": "memory"
|
||||
}, {
|
||||
"type": "bitmap",
|
||||
"name": "ICON_BATTERY_FULL",
|
||||
"file": "icon_battery_full.png",
|
||||
"memoryFormat": "Smallest",
|
||||
"spaceOptimization": "memory"
|
||||
}, {
|
||||
"type": "bitmap",
|
||||
"name": "ICON_PAWS",
|
||||
"file": "icon_paws.png",
|
||||
"memoryFormat": "Smallest",
|
||||
"spaceOptimization": "memory"
|
||||
}, {
|
||||
"type": "font",
|
||||
"name": "FONT_TORO_36",
|
||||
|
|
|
|||
BIN
resources/icon_battery_empty.png
Normal file
BIN
resources/icon_battery_empty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 130 B |
BIN
resources/icon_battery_full.png
Normal file
BIN
resources/icon_battery_full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 143 B |
BIN
resources/icon_battery_half.png
Normal file
BIN
resources/icon_battery_half.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 143 B |
BIN
resources/icon_paws.png
Normal file
BIN
resources/icon_paws.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 213 B |
|
|
@ -60,6 +60,10 @@ void clock_layer_init(Layer *layer, int y) {
|
|||
layer_add_child(layer, s_clock_layer);
|
||||
}
|
||||
|
||||
GRect clock_layer_get_bounds() {
|
||||
return layer_get_bounds(s_clock_layer);
|
||||
}
|
||||
|
||||
void clock_layer_tick(void) {
|
||||
layer_mark_dirty(s_clock_layer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
#include <pebble.h>
|
||||
|
||||
void clock_layer_init(Layer *layer, int y);
|
||||
GRect clock_layer_get_bounds();
|
||||
void clock_layer_tick(void);
|
||||
void clock_layer_deinit(void);
|
||||
|
||||
#endif
|
||||
#endif // CLOCK_LAYER_H_
|
||||
|
|
|
|||
115
src/c/information_layer.c
Normal file
115
src/c/information_layer.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include "information_layer.h"
|
||||
|
||||
#include "resources_service.h"
|
||||
|
||||
#define INFO_LAYER_ICON_WIDTH 18
|
||||
#define INFO_LAYER_PADDING 4
|
||||
#define INFO_LAYER_HEIGHT 24
|
||||
|
||||
typedef struct InformationLayerData {
|
||||
int level;
|
||||
int steps;
|
||||
} InformationLayerData;
|
||||
|
||||
static Layer *s_information_layer;
|
||||
static char s_information_layer_level_text[3];
|
||||
static char s_information_layer_count_text[6];
|
||||
|
||||
static void information_layer_update_proc(Layer *layer, GContext *ctx) {
|
||||
GRect rect = layer_get_unobstructed_bounds(layer);
|
||||
GFont font = resources_service_get_custom_font(CustomFontKonekoToro);
|
||||
InformationLayerData *data = layer_get_data(s_information_layer);
|
||||
|
||||
int content_w = INFO_LAYER_ICON_WIDTH + INFO_LAYER_PADDING;
|
||||
|
||||
snprintf(s_information_layer_level_text, sizeof(s_information_layer_level_text), "%d",
|
||||
data->level);
|
||||
GSize text_size = graphics_text_layout_get_content_size(
|
||||
s_information_layer_level_text, font, rect, GTextOverflowModeFill, GTextAlignmentLeft);
|
||||
content_w += text_size.w;
|
||||
|
||||
#ifdef PBL_HEALTH
|
||||
snprintf(s_information_layer_count_text, sizeof(s_information_layer_count_text), "%d",
|
||||
data->steps);
|
||||
text_size = graphics_text_layout_get_content_size(s_information_layer_count_text, font, rect,
|
||||
GTextOverflowModeFill, GTextAlignmentLeft);
|
||||
content_w += INFO_LAYER_ICON_WIDTH + INFO_LAYER_PADDING + text_size.w;
|
||||
#endif
|
||||
|
||||
int content_x = (rect.size.w - content_w) / 2;
|
||||
|
||||
/* Draw the battery icon based on level percentage. */
|
||||
graphics_context_set_compositing_mode(ctx, GCompOpSet);
|
||||
|
||||
GBitmap *battery_icon;
|
||||
if (data->level < 20) {
|
||||
battery_icon = resources_service_get_custom_icon(CustomIconBatteryEmpty);
|
||||
} else if (data->level < 80) {
|
||||
battery_icon = resources_service_get_custom_icon(CustomIconBatteryHalf);
|
||||
} else {
|
||||
battery_icon = resources_service_get_custom_icon(CustomIconBatteryFull);
|
||||
}
|
||||
|
||||
GRect battery_rect_inside = GRect(0, 0, INFO_LAYER_ICON_WIDTH, rect.size.h);
|
||||
GRect battery_rect = gbitmap_get_bounds(battery_icon);
|
||||
grect_align(&battery_rect, &battery_rect_inside, GAlignCenter, true);
|
||||
battery_rect.origin.x += content_x;
|
||||
graphics_draw_bitmap_in_rect(ctx, battery_icon, battery_rect);
|
||||
|
||||
/* Draw the battery level in text. */
|
||||
GRect text_rect =
|
||||
GRect(content_x + INFO_LAYER_ICON_WIDTH + INFO_LAYER_PADDING, -4, text_size.w, text_size.h);
|
||||
|
||||
graphics_context_set_text_color(ctx, GColorBlack);
|
||||
graphics_draw_text(ctx, s_information_layer_level_text, font, text_rect, GTextOverflowModeFill,
|
||||
GTextAlignmentLeft, NULL);
|
||||
|
||||
#ifdef PBL_HEALTH
|
||||
/* Draw the paws icon. */
|
||||
GBitmap *paws_icon = resources_service_get_custom_icon(CustomIconPaws);
|
||||
GRect paws_rect = gbitmap_get_bounds(paws_icon);
|
||||
paws_rect.origin.x = content_x + text_rect.size.w;
|
||||
graphics_draw_bitmap_in_rect(ctx, paws_icon, paws_rect);
|
||||
|
||||
/* Draw the step count in text. */
|
||||
text_rect = GRect(paws_rect.origin.x + INFO_LAYER_ICON_WIDTH + INFO_LAYER_PADDING, -4,
|
||||
text_size.w, text_size.h);
|
||||
graphics_context_set_text_color(ctx, GColorBlack);
|
||||
graphics_draw_text(ctx, s_information_layer_count_text, font, text_rect, GTextOverflowModeFill,
|
||||
GTextAlignmentLeft, NULL);
|
||||
#endif // PBL_HEALTH
|
||||
}
|
||||
|
||||
static void battery_state_service_callback(BatteryChargeState charge) {
|
||||
InformationLayerData *data = layer_get_data(s_information_layer);
|
||||
data->level = charge.charge_percent;
|
||||
layer_mark_dirty(s_information_layer);
|
||||
}
|
||||
|
||||
void information_layer_init(Layer *layer, int y) {
|
||||
GRect rect = layer_get_unobstructed_bounds(layer);
|
||||
|
||||
s_information_layer = layer_create_with_data(GRect(0, y, rect.size.w, INFO_LAYER_HEIGHT),
|
||||
sizeof(InformationLayerData));
|
||||
|
||||
InformationLayerData *data = layer_get_data(s_information_layer);
|
||||
data->level = battery_state_service_peek().charge_percent;
|
||||
data->steps = PBL_IF_HEALTH_ELSE(health_service_sum_today(HealthMetricStepCount), 0);
|
||||
|
||||
layer_set_update_proc(s_information_layer, information_layer_update_proc);
|
||||
layer_add_child(layer, s_information_layer);
|
||||
|
||||
battery_state_service_subscribe(battery_state_service_callback);
|
||||
}
|
||||
|
||||
void information_layer_tick(void) {
|
||||
#ifdef PBL_HEALTH
|
||||
InformationLayerData *data = layer_get_data(s_information_layer);
|
||||
data->steps = health_service_sum_today(HealthMetricStepCount);
|
||||
layer_mark_dirty(s_information_layer);
|
||||
#endif // PBL_HEALTH
|
||||
}
|
||||
|
||||
void information_layer_deinit(void) {
|
||||
layer_destroy(s_information_layer);
|
||||
}
|
||||
10
src/c/information_layer.h
Normal file
10
src/c/information_layer.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef INFORMATION_LAYER_H_
|
||||
#define INFORMATION_LAYER_H_
|
||||
|
||||
#include <pebble.h>
|
||||
|
||||
void information_layer_init(Layer *layer, int y);
|
||||
void information_layer_tick(void);
|
||||
void information_layer_deinit(void);
|
||||
|
||||
#endif // INFORMATION_LAYER_H_
|
||||
|
|
@ -2,12 +2,14 @@
|
|||
#include "date_layer.h"
|
||||
#include "character_layer.h"
|
||||
#include "clock_layer.h"
|
||||
#include "information_layer.h"
|
||||
|
||||
static Window *s_main_window;
|
||||
|
||||
static void main_window_tick(struct tm *time, TimeUnits units) {
|
||||
date_layer_tick();
|
||||
clock_layer_tick();
|
||||
information_layer_tick();
|
||||
character_layer_tick();
|
||||
}
|
||||
|
||||
|
|
@ -15,7 +17,11 @@ static void main_window_load(Window *window) {
|
|||
Layer *layer = window_get_root_layer(window);
|
||||
|
||||
date_layer_init(layer, 0);
|
||||
clock_layer_init(layer, 40);
|
||||
clock_layer_init(layer, 30);
|
||||
|
||||
GRect clock_layer_rect = clock_layer_get_bounds();
|
||||
information_layer_init(layer, 30 + clock_layer_rect.size.h + 4);
|
||||
|
||||
character_layer_init(layer);
|
||||
|
||||
tick_timer_service_subscribe(SECOND_UNIT, main_window_tick);
|
||||
|
|
@ -26,6 +32,7 @@ static void main_window_unload(Window *window) {
|
|||
|
||||
clock_layer_deinit();
|
||||
date_layer_deinit();
|
||||
information_layer_deinit();
|
||||
character_layer_deinit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,25 +8,41 @@ typedef struct ResourcesService {
|
|||
GFont font_toro;
|
||||
GBitmap *character_even;
|
||||
GBitmap *character_odd;
|
||||
GBitmap *icon_battery_empty;
|
||||
GBitmap *icon_battery_half;
|
||||
GBitmap *icon_battery_full;
|
||||
GBitmap *icon_paws;
|
||||
} ResourcesService;
|
||||
|
||||
static ResourcesService *s_resources_service;
|
||||
|
||||
void resources_service_init(void) {
|
||||
s_resources_service = malloc(sizeof(ResourcesService));
|
||||
|
||||
s_resources_service->font_koneko_toro =
|
||||
fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_KONEKO_TORO));
|
||||
s_resources_service->font_toro =
|
||||
fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_TORO));
|
||||
|
||||
s_resources_service->character_even = gbitmap_create_with_resource(RESOURCE_ID_CHARACTER_EVEN);
|
||||
s_resources_service->character_odd = gbitmap_create_with_resource(RESOURCE_ID_CHARACTER_ODD);
|
||||
|
||||
s_resources_service->icon_battery_empty =
|
||||
gbitmap_create_with_resource(RESOURCE_ID_ICON_BATTERY_EMPTY);
|
||||
s_resources_service->icon_battery_full =
|
||||
gbitmap_create_with_resource(RESOURCE_ID_ICON_BATTERY_FULL);
|
||||
s_resources_service->icon_battery_half =
|
||||
gbitmap_create_with_resource(RESOURCE_ID_ICON_BATTERY_HALF);
|
||||
s_resources_service->icon_paws = gbitmap_create_with_resource(RESOURCE_ID_ICON_PAWS);
|
||||
}
|
||||
|
||||
void resources_service_deinit(void) {
|
||||
fonts_unload_custom_font(s_resources_service->font_koneko_toro);
|
||||
fonts_unload_custom_font(s_resources_service->font_toro);
|
||||
|
||||
gbitmap_destroy(s_resources_service->character_even);
|
||||
gbitmap_destroy(s_resources_service->character_odd);
|
||||
|
||||
free(s_resources_service);
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +53,20 @@ GBitmap *resources_service_get_character(int ticks) {
|
|||
return s_resources_service->character_odd;
|
||||
}
|
||||
|
||||
GBitmap *resources_service_get_custom_icon(CustomIcon icon) {
|
||||
switch (icon) {
|
||||
case CustomIconBatteryEmpty:
|
||||
return s_resources_service->icon_battery_empty;
|
||||
case CustomIconBatteryFull:
|
||||
return s_resources_service->icon_battery_full;
|
||||
case CustomIconBatteryHalf:
|
||||
return s_resources_service->icon_battery_half;
|
||||
case CustomIconPaws:
|
||||
return s_resources_service->icon_paws;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GFont resources_service_get_custom_font(CustomFont font) {
|
||||
switch (font) {
|
||||
case CustomFontKonekoToro:
|
||||
|
|
@ -44,5 +74,5 @@ GFont resources_service_get_custom_font(CustomFont font) {
|
|||
case CustomFontToro:
|
||||
return s_resources_service->font_toro;
|
||||
}
|
||||
return NULL;
|
||||
return fonts_get_system_font(FONT_KEY_FONT_FALLBACK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,18 @@ typedef enum CustomFont {
|
|||
CustomFontToro
|
||||
} CustomFont;
|
||||
|
||||
typedef enum CustomIcon {
|
||||
CustomIconBatteryEmpty,
|
||||
CustomIconBatteryFull,
|
||||
CustomIconBatteryHalf,
|
||||
CustomIconPaws
|
||||
} CustomIcon;
|
||||
|
||||
void resources_service_init(void);
|
||||
void resources_service_deinit(void);
|
||||
|
||||
GBitmap *resources_service_get_character(int ticks);
|
||||
GBitmap *resources_service_get_custom_icon(CustomIcon icon);
|
||||
GFont resources_service_get_custom_font(CustomFont font);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue