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
+3
View File
@@ -0,0 +1,3 @@
[submodule "neat_bar"]
path = neat_bar
url = https://git.wetfence.xyz/RandyTheSilly/neat_bar.git
Submodule
+1
Submodule neat_bar added at 5320565b54
+59 -31
View File
@@ -1,8 +1,9 @@
#include "../../neat_bar/src/c/neat_bar.h"
#include <pebble.h> #include <pebble.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
// #define DEBUG_MODE 1 #define DEBUG_MODE 1
// declare settings-derived statics // declare settings-derived statics
static uint8_t s_is_jellyfin; static uint8_t s_is_jellyfin;
@@ -20,18 +21,21 @@ static Window *s_main_window;
static TextLayer *s_config_app_layer; static TextLayer *s_config_app_layer;
static TextLayer *s_sleep_time_layer; static TextLayer *s_sleep_time_layer;
static TextLayer *s_last_watched_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 Layer *s_sleep_bar_layer;
static BitmapLayer *s_logo_layer; static BitmapLayer *s_logo_layer;
static const uint8_t s_logo_width = 25; static const uint8_t s_logo_width = 25;
#define MARGIN 8
#if PBL_ROUND #if PBL_ROUND
#define NEAT_BAR_WIDTH 30
#if PBL_DISPLAY_WIDTH >= 260 #if PBL_DISPLAY_WIDTH >= 260
static const uint8_t s_sleep_bar_drop = 54; static const uint8_t s_sleep_bar_drop = 54;
#else #else
static const uint8_t s_sleep_bar_drop = 50; static const uint8_t s_sleep_bar_drop = 50;
#endif #endif
#else #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 #endif
#if PBL_DISPLAY_WIDTH >= 200 #if PBL_DISPLAY_WIDTH >= 200
#define LW_FONT_SIZE 28 #define LW_FONT_SIZE 28
@@ -49,9 +53,7 @@ static bool s_sleep_session_found;
static bool s_sleep_data_accessible; 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_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 - PBL_IF_ROUND_ELSE(MARGIN / 2, MARGIN) + s_wasted_top_text_pixels;
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_screen_center_y = PBL_DISPLAY_HEIGHT / 2; 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 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) { 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; // 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 // 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) { 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)); 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); 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) { static void sleep_bar_update_proc(Layer *layer, GContext *ctx) {
graphics_context_set_fill_color(ctx, s_color_primary); 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() { static void send_pin_to_pkjs() {
@@ -143,10 +140,10 @@ static void main_window_load(Window *window) {
if (s_is_jellyfin == 0) { if (s_is_jellyfin == 0) {
window_set_background_color(window, GColorWhite); window_set_background_color(window, GColorWhite);
#if PBL_DISPLAY_WIDTH >= 200 #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)); text_layer_set_font(s_config_app_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
#else #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))); 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 #endif
text_layer_set_background_color(s_config_app_layer, GColorClear); text_layer_set_background_color(s_config_app_layer, GColorClear);
@@ -157,14 +154,34 @@ static void main_window_load(Window *window) {
} }
// action bar // action bar
s_action_bar_layer = action_bar_layer_create(); s_neat_bar_layer = neat_bar_layer_create();
action_bar_layer_set_click_config_provider(s_action_bar_layer, click_config_provider); neat_bar_layer_set_icon(s_neat_bar_layer, BUTTON_ID_UP, s_prev_icon);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_UP, s_prev_icon); neat_bar_layer_set_icon(s_neat_bar_layer, BUTTON_ID_SELECT, s_pin_icon);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_SELECT, s_pin_icon); neat_bar_layer_set_icon(s_neat_bar_layer, BUTTON_ID_DOWN, s_next_icon);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_DOWN, s_next_icon); neat_bar_layer_set_background_color(s_neat_bar_layer, s_color_secondary);
action_bar_layer_set_background_color(s_action_bar_layer, s_color_secondary); neat_bar_layer_set_width(s_neat_bar_layer, NEAT_BAR_WIDTH);
action_bar_layer_set_icon_press_animation(s_action_bar_layer, BUTTON_ID_SELECT, ActionBarLayerIconPressAnimationMoveLeft); #if PBL_DISPLAY_HEIGHT >= 260 && PBL_ROUND
action_bar_layer_add_to_window(s_action_bar_layer, window); 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 // sleep bar and icon
s_sleep_bar_layer = layer_create(s_sleep_bar_start); 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_compositing_mode(s_logo_layer, GCompOpSet);
bitmap_layer_set_bitmap(s_logo_layer, s_logo_icon); 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 #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_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)); text_layer_set_font(s_last_watched_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28));
#else #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_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)); text_layer_set_font(s_last_watched_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24));
#endif #endif
@@ -200,9 +217,9 @@ static void main_window_load(Window *window) {
} else { } else {
#if PBL_RECT #if PBL_RECT
#if PBL_DISPLAY_WIDTH >= 200 #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 #else
text_layer_set_text(s_sleep_time_layer, " No sleep time"); text_layer_set_text(s_sleep_time_layer, " No sleep time");
#endif #endif
#else #else
text_layer_set_text(s_sleep_time_layer, "No sleep time found"); 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); text_layer_destroy(s_sleep_time_layer);
bitmap_layer_destroy(s_logo_layer); bitmap_layer_destroy(s_logo_layer);
layer_destroy(s_sleep_bar_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); Tuple *watched_tuple = dict_find(iter, MESSAGE_KEY_PKJS_LAST_WATCHED);
if (watched_tuple) { if (watched_tuple) {
write_last_watched(watched_tuple->value->cstring); 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 *sleep_bar_anim = property_animation_get_animation(sleep_bar_prop);
animation_set_duration(sleep_bar_anim, 512); 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 *logo_anim = property_animation_get_animation(logo_prop);
animation_set_duration(logo_anim, 512); animation_set_duration(logo_anim, 512);
Animation *load_spawn_anim = animation_spawn_create(sleep_bar_anim, logo_anim, NULL); Animation *load_spawn_anim = animation_spawn_create(sleep_bar_anim, logo_anim, NULL);
+2 -1
View File
@@ -34,7 +34,8 @@ def build(ctx):
ctx.env = ctx.all_envs[platform] ctx.env = ctx.all_envs[platform]
ctx.set_group(ctx.env.PLATFORM_NAME) ctx.set_group(ctx.env.PLATFORM_NAME)
app_elf = '{}/pebble-app.elf'.format(ctx.env.BUILD_DIR) app_elf = '{}/pebble-app.elf'.format(ctx.env.BUILD_DIR)
ctx.pbl_build(source=ctx.path.ant_glob('src/c/**/*.c'), target=app_elf, bin_type='app') ctx.pbl_build(source=ctx.path.ant_glob(['src/c/**/*.c', 'neat_bar/src/c/**/*.c']), target=app_elf, bin_type='app')
if build_worker: if build_worker:
worker_elf = '{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR) worker_elf = '{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR)