UI overhaul w/neat_bar

This commit is contained in:
2026-07-19 17:27:31 -04:00
parent 0ab885d7ae
commit d84edb5429
4 changed files with 65 additions and 32 deletions
+59 -31
View File
@@ -1,8 +1,9 @@
#include "../../neat_bar/src/c/neat_bar.h"
#include <pebble.h>
#include <stdio.h>
#include <string.h>
// #define DEBUG_MODE 1
#define DEBUG_MODE 1
// declare settings-derived statics
static uint8_t s_is_jellyfin;
@@ -20,18 +21,21 @@ static Window *s_main_window;
static TextLayer *s_config_app_layer;
static TextLayer *s_sleep_time_layer;
static TextLayer *s_last_watched_layer;
static ActionBarLayer *s_action_bar_layer;
static NeatBarLayer *s_neat_bar_layer;
static Layer *s_sleep_bar_layer;
static BitmapLayer *s_logo_layer;
static const uint8_t s_logo_width = 25;
#define MARGIN 8
#if PBL_ROUND
#define NEAT_BAR_WIDTH 30
#if PBL_DISPLAY_WIDTH >= 260
static const uint8_t s_sleep_bar_drop = 54;
#else
static const uint8_t s_sleep_bar_drop = 50;
#endif
#else
static const uint8_t s_sleep_bar_drop = 34;
#define NEAT_BAR_WIDTH 25
static const uint8_t s_sleep_bar_drop = 37;
#endif
#if PBL_DISPLAY_WIDTH >= 200
#define LW_FONT_SIZE 28
@@ -49,9 +53,7 @@ static bool s_sleep_session_found;
static bool s_sleep_data_accessible;
static const uint8_t s_wasted_top_text_pixels = 10; // 10 blank pixels above each line of text
static const uint8_t s_margin = PBL_DISPLAY_WIDTH / 35;
static const uint16_t s_available_height = PBL_DISPLAY_HEIGHT - s_sleep_bar_drop - s_margin + s_wasted_top_text_pixels;
// static const uint8_t s_max_rows = s_available_height / LW_FONT_SIZE;
static const uint16_t s_available_height = PBL_DISPLAY_HEIGHT - s_sleep_bar_drop - PBL_IF_ROUND_ELSE(MARGIN / 2, MARGIN) + s_wasted_top_text_pixels;
static const uint16_t s_screen_center_y = PBL_DISPLAY_HEIGHT / 2;
static const uint16_t s_base_shift = s_screen_center_y - (LW_FONT_SIZE / 2) - (s_wasted_top_text_pixels / 2); // base - perfect if there is one row
static void write_last_watched(const char *text) {
@@ -66,7 +68,7 @@ static void write_last_watched(const char *text) {
// if the top extends above the sleep bar, force it below it;
// account for blank pixels above text to avoid forcing position when not visually necessary
if (y + s_wasted_top_text_pixels < s_sleep_bar_drop) {
y = s_sleep_bar_drop - s_wasted_top_text_pixels + s_margin;
y = s_sleep_bar_drop - s_wasted_top_text_pixels + s_available_height;
}
GRect last_watched_frame = layer_get_frame(text_layer_get_layer(s_last_watched_layer));
@@ -86,14 +88,9 @@ static void update_sleep_time(time_t start, time_t end) {
cb_update_sleep_time, NULL);
}
static void button_bar_update_proc(Layer *layer, GContext *ctx) {
graphics_context_set_fill_color(ctx, s_color_secondary);
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
}
static void sleep_bar_update_proc(Layer *layer, GContext *ctx) {
graphics_context_set_fill_color(ctx, s_color_primary);
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
graphics_fill_rect(ctx, layer_get_bounds(layer), PBL_IF_ROUND_ELSE(15, 3), PBL_IF_ROUND_ELSE(GCornersBottom, GCornersAll));
}
static void send_pin_to_pkjs() {
@@ -143,10 +140,10 @@ static void main_window_load(Window *window) {
if (s_is_jellyfin == 0) {
window_set_background_color(window, GColorWhite);
#if PBL_DISPLAY_WIDTH >= 200
s_config_app_layer = text_layer_create(GRect(s_margin, (PBL_DISPLAY_HEIGHT / 2) - PBL_IF_ROUND_ELSE(33, 49), PBL_DISPLAY_WIDTH - 8, PBL_DISPLAY_HEIGHT));
s_config_app_layer = text_layer_create(GRect(MARGIN, (PBL_DISPLAY_HEIGHT / 2) - PBL_IF_ROUND_ELSE(33, 49), PBL_DISPLAY_WIDTH - 8, PBL_DISPLAY_HEIGHT));
text_layer_set_font(s_config_app_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
#else
s_config_app_layer = text_layer_create(GRect(s_margin, (PBL_DISPLAY_HEIGHT / 2) - PBL_IF_ROUND_ELSE(43, 32), PBL_DISPLAY_WIDTH - 8, PBL_DISPLAY_HEIGHT));
s_config_app_layer = text_layer_create(GRect(MARGIN, (PBL_DISPLAY_HEIGHT / 2) - PBL_IF_ROUND_ELSE(43, 32), PBL_DISPLAY_WIDTH - 8, PBL_DISPLAY_HEIGHT));
text_layer_set_font(s_config_app_layer, fonts_get_system_font(PBL_IF_ROUND_ELSE(FONT_KEY_GOTHIC_24_BOLD, FONT_KEY_GOTHIC_18_BOLD)));
#endif
text_layer_set_background_color(s_config_app_layer, GColorClear);
@@ -157,14 +154,34 @@ static void main_window_load(Window *window) {
}
// action bar
s_action_bar_layer = action_bar_layer_create();
action_bar_layer_set_click_config_provider(s_action_bar_layer, click_config_provider);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_UP, s_prev_icon);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_SELECT, s_pin_icon);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_DOWN, s_next_icon);
action_bar_layer_set_background_color(s_action_bar_layer, s_color_secondary);
action_bar_layer_set_icon_press_animation(s_action_bar_layer, BUTTON_ID_SELECT, ActionBarLayerIconPressAnimationMoveLeft);
action_bar_layer_add_to_window(s_action_bar_layer, window);
s_neat_bar_layer = neat_bar_layer_create();
neat_bar_layer_set_icon(s_neat_bar_layer, BUTTON_ID_UP, s_prev_icon);
neat_bar_layer_set_icon(s_neat_bar_layer, BUTTON_ID_SELECT, s_pin_icon);
neat_bar_layer_set_icon(s_neat_bar_layer, BUTTON_ID_DOWN, s_next_icon);
neat_bar_layer_set_background_color(s_neat_bar_layer, s_color_secondary);
neat_bar_layer_set_width(s_neat_bar_layer, NEAT_BAR_WIDTH);
#if PBL_DISPLAY_HEIGHT >= 260 && PBL_ROUND
neat_bar_layer_set_corner_radius(s_neat_bar_layer, 15);
neat_bar_layer_set_height(s_neat_bar_layer, 140);
neat_bar_layer_set_y_offset(s_neat_bar_layer, 60);
#elif PBL_DISPLAY_HEIGHT == 228 && PBL_RECT
neat_bar_layer_set_corner_radius(s_neat_bar_layer, 3);
neat_bar_layer_set_floating(s_neat_bar_layer, 4);
neat_bar_layer_set_height(s_neat_bar_layer, 183);
neat_bar_layer_set_y_offset(s_neat_bar_layer, 41);
#elif PBL_DISPLAY_HEIGHT == 180 && PBL_ROUND
neat_bar_layer_set_corner_radius(s_neat_bar_layer, 15);
neat_bar_layer_set_height(s_neat_bar_layer, 71);
neat_bar_layer_set_y_offset(s_neat_bar_layer, 54);
#else // 144x168
neat_bar_layer_set_corner_radius(s_neat_bar_layer, 3);
neat_bar_layer_set_floating(s_neat_bar_layer, 4);
neat_bar_layer_set_height(s_neat_bar_layer, 123);
neat_bar_layer_set_y_offset(s_neat_bar_layer, 41);
neat_bar_layer_set_spread(s_neat_bar_layer, -10);
#endif
neat_bar_layer_set_click_config_provider(s_neat_bar_layer, click_config_provider);
neat_bar_layer_add_to_window(s_neat_bar_layer, window);
// sleep bar and icon
s_sleep_bar_layer = layer_create(s_sleep_bar_start);
@@ -172,13 +189,13 @@ static void main_window_load(Window *window) {
bitmap_layer_set_compositing_mode(s_logo_layer, GCompOpSet);
bitmap_layer_set_bitmap(s_logo_layer, s_logo_icon);
s_last_watched_layer = text_layer_create(GRect(s_margin, 0, PBL_DISPLAY_WIDTH - (2 * s_margin) - ACTION_BAR_WIDTH, s_available_height)); // y position updated when layer is written to
s_last_watched_layer = text_layer_create(GRect(MARGIN, 0, PBL_DISPLAY_WIDTH - (2 * MARGIN) - NEAT_BAR_WIDTH - PBL_IF_ROUND_ELSE(0, MARGIN / 2), s_available_height)); // y position updated when layer is written to
#if PBL_DISPLAY_WIDTH >= 200
s_sleep_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(22, 2), PBL_DISPLAY_WIDTH, 30));
s_sleep_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(22, 5), PBL_DISPLAY_WIDTH, 30));
text_layer_set_font(s_sleep_time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
text_layer_set_font(s_last_watched_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28));
#else
s_sleep_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(25, 2), PBL_DISPLAY_WIDTH, 30));
s_sleep_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(25, 5), PBL_DISPLAY_WIDTH, 30));
text_layer_set_font(s_sleep_time_layer, fonts_get_system_font(PBL_IF_ROUND_ELSE(FONT_KEY_GOTHIC_18_BOLD, FONT_KEY_GOTHIC_24_BOLD)));
text_layer_set_font(s_last_watched_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24));
#endif
@@ -200,9 +217,9 @@ static void main_window_load(Window *window) {
} else {
#if PBL_RECT
#if PBL_DISPLAY_WIDTH >= 200
text_layer_set_text(s_sleep_time_layer, " No sleep time found");
text_layer_set_text(s_sleep_time_layer, " No sleep time found");
#else
text_layer_set_text(s_sleep_time_layer, " No sleep time");
text_layer_set_text(s_sleep_time_layer, " No sleep time");
#endif
#else
text_layer_set_text(s_sleep_time_layer, "No sleep time found");
@@ -236,7 +253,7 @@ static void main_window_unload(Window *window) {
text_layer_destroy(s_sleep_time_layer);
bitmap_layer_destroy(s_logo_layer);
layer_destroy(s_sleep_bar_layer);
action_bar_layer_destroy(s_action_bar_layer);
// action_bar_layer_destroy(s_action_bar_layer);
}
}
@@ -311,10 +328,21 @@ static void inbox_received_handler(DictionaryIterator *iter, void *context) {
Tuple *watched_tuple = dict_find(iter, MESSAGE_KEY_PKJS_LAST_WATCHED);
if (watched_tuple) {
write_last_watched(watched_tuple->value->cstring);
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(0, -PBL_DISPLAY_HEIGHT + s_sleep_bar_drop, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT));
#if PBL_ROUND
#if PBL_DISPLAY_WIDTH >= 260
#define r_x 30
#define r_w 200
#else
#define r_x 15
#define r_w 150
#endif
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(r_x, 0, r_w, s_sleep_bar_drop));
#else
PropertyAnimation *sleep_bar_prop = property_animation_create_layer_frame(s_sleep_bar_layer, &s_sleep_bar_start, &GRect(4, 4, PBL_DISPLAY_WIDTH - 8, s_sleep_bar_drop - 4));
#endif
Animation *sleep_bar_anim = property_animation_get_animation(sleep_bar_prop);
animation_set_duration(sleep_bar_anim, 512);
PropertyAnimation *logo_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_logo_layer), &s_logo_start, &GRect(PBL_IF_ROUND_ELSE((PBL_DISPLAY_WIDTH / 2) - 13, s_margin), 3, s_logo_width, s_logo_width));
PropertyAnimation *logo_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_logo_layer), &s_logo_start, &GRect(PBL_IF_ROUND_ELSE((PBL_DISPLAY_WIDTH / 2) - 13, MARGIN), PBL_IF_ROUND_ELSE(3, 6), s_logo_width, s_logo_width));
Animation *logo_anim = property_animation_get_animation(logo_prop);
animation_set_duration(logo_anim, 512);
Animation *load_spawn_anim = animation_spawn_create(sleep_bar_anim, logo_anim, NULL);