diff --git a/main/pages/login/login.c b/main/pages/login/login.c index 3153f21..ba7693a 100644 --- a/main/pages/login/login.c +++ b/main/pages/login/login.c @@ -87,7 +87,7 @@ void login_page_create(lv_obj_t *parent) { login_screen = theme_create_page_container(parent); // Match the brand wordmark exactly: white uppercase "KERN" in the medium - // font, with a pulsing Kern logo to its left (reusing the screensaver fade). + // font, with a static Kern logo to its left. login_menu = ui_menu_create(login_screen, "KERN", NULL); lv_obj_t *title = ui_menu_get_title_label(login_menu); if (title) { @@ -121,10 +121,10 @@ void login_page_create(lv_obj_t *parent) { // it doesn't deserve a full-width tile). about_button = ui_create_info_button(login_screen, about_cb); - // Pulsing Kern logo to the left of the title, sized to the title cap height. + // Static Kern logo to the left of the title, sized to the title cap height. if (title) { int32_t logo_sz = lv_font_get_line_height(theme_font_medium()); - lv_obj_t *logo = kern_logo_create_pulsing(login_screen, logo_sz); + lv_obj_t *logo = kern_logo_create(login_screen, 0, 0, logo_sz); lv_obj_update_layout(login_screen); lv_obj_align_to(logo, title, LV_ALIGN_OUT_LEFT_MID, -theme_get_small_padding(), 0); diff --git a/main/pages/screensaver.c b/main/pages/screensaver.c index 1217f4a..4616caa 100644 --- a/main/pages/screensaver.c +++ b/main/pages/screensaver.c @@ -72,7 +72,9 @@ void screensaver_destroy(void) { active = false; if (!scr_container) return; - // Deleting the container cascades to the rings, removing their animations. + // Stop the ring fade before teardown so no animation callback fires during + // the async dismiss; deleting the container then cascades to the rings. + kern_logo_stop_fade(logo); lv_obj_delete(scr_container); scr_container = NULL; logo = NULL; diff --git a/main/ui/assets/kern_logo_lvgl.c b/main/ui/assets/kern_logo_lvgl.c index 5fab39d..53fb6cf 100644 --- a/main/ui/assets/kern_logo_lvgl.c +++ b/main/ui/assets/kern_logo_lvgl.c @@ -165,31 +165,21 @@ void kern_logo_fade_cycle(lv_obj_t *logo, lv_anim_completed_cb_t done_cb, fade_ring(lv_obj_get_child(logo, 0), 2 * LOGO_STAGGER, LOGO_HOLD, NULL, NULL); } -static void logo_pulse_loop_cb(lv_anim_t *a) { - lv_obj_t *logo = lv_anim_get_user_data(a); - kern_logo_fade_cycle(logo, logo_pulse_loop_cb, logo); -} - -/** Create a logo symbol whose rings continuously fade in and out in place. */ -lv_obj_t *kern_logo_create_pulsing(lv_obj_t *parent, int32_t size) { - lv_obj_t *logo = kern_logo_create(parent, 0, 0, size); - kern_logo_fade_cycle(logo, logo_pulse_loop_cb, logo); - return logo; -} - -/** Create logo with text, horizontally centered at top */ -lv_obj_t *kern_logo_with_text(lv_obj_t *parent, int32_t x, int32_t y) { - int32_t sz = theme_get_logo_size() * 160 / 200; - lv_obj_t *c = - create_flex_container(parent, LV_ALIGN_TOP_MID, sz * TEXT_GAP_PCT / 100); - lv_obj_align(c, LV_ALIGN_TOP_MID, x, y); - kern_logo_create(c, 0, 0, sz); - create_label(c, sz); - return c; +/* Stop a fade cycle by removing the opacity animations from the logo's three + * rings, so nothing keeps invalidating (and forcing redraws) once the logo is + * hidden or about to be destroyed. Safe on a logo that isn't animating. */ +void kern_logo_stop_fade(lv_obj_t *logo) { + if (!logo) + return; + for (int i = 0; i < 3; i++) { + lv_obj_t *ring = lv_obj_get_child(logo, i); + if (ring) + lv_anim_delete(ring, anim_opa_cb); + } } -/** Same as kern_logo_with_text_inline, with an explicit logo diameter so the - * caller can scale the whole symbol+wordmark block to fit a layout budget. */ +/** Logo + "KERN" wordmark as a flex-friendly child, with an explicit logo + * diameter so the caller can scale the whole block to fit a layout budget. */ lv_obj_t *kern_logo_with_text_inline_sized(lv_obj_t *parent, int32_t sz) { lv_obj_t *c = lv_obj_create(parent); lv_obj_remove_style_all(c); @@ -204,12 +194,6 @@ lv_obj_t *kern_logo_with_text_inline_sized(lv_obj_t *parent, int32_t sz) { return c; } -/** Create logo with text as a flex-friendly child (no forced alignment) */ -lv_obj_t *kern_logo_with_text_inline(lv_obj_t *parent) { - return kern_logo_with_text_inline_sized(parent, - theme_get_logo_size() * 160 / 200); -} - /** Animated logo with text for boot screen, vertically centered */ void kern_logo_animated(lv_obj_t *parent) { int32_t size = theme_get_logo_size(); diff --git a/main/ui/assets/kern_logo_lvgl.h b/main/ui/assets/kern_logo_lvgl.h index 84b8d49..3be8950 100644 --- a/main/ui/assets/kern_logo_lvgl.h +++ b/main/ui/assets/kern_logo_lvgl.h @@ -26,16 +26,6 @@ extern "C" { lv_obj_t *kern_logo_create(lv_obj_t *parent, lv_coord_t x, lv_coord_t y, lv_coord_t size); -/** - * Create a logo symbol whose rings continuously fade in and out in place, - * mirroring the screensaver pulse. Useful as a small animated brand mark. - * - * @param parent Parent LVGL object - * @param size Logo diameter in pixels - * @return Pointer to created logo container - */ -lv_obj_t *kern_logo_create_pulsing(lv_obj_t *parent, lv_coord_t size); - /** * Run one staggered fade-in/out cycle on a logo's three rings. When the cycle * ends, done_cb fires (with user_data set on the animation) — loop it for a @@ -49,27 +39,21 @@ void kern_logo_fade_cycle(lv_obj_t *logo, lv_anim_completed_cb_t done_cb, void *user_data); /** - * Create logo with "KERN" text combo - * This matches the "Minimal variant" from Typography Combinations + * Stop a fade cycle started by kern_logo_fade_cycle, removing the opacity + * animations from the logo's rings. Call before hiding or destroying a logo so + * a lingering animation can't keep invalidating the screen. * - * @param parent Parent LVGL object - * @param x X coordinate - * @param y Y coordinate - * @return Pointer to created container object + * @param logo Logo container from kern_logo_create */ -lv_obj_t *kern_logo_with_text(lv_obj_t *parent, lv_coord_t x, lv_coord_t y); +void kern_logo_stop_fade(lv_obj_t *logo); /** - * Create logo with text as a flex-friendly child (no forced alignment) + * Create the logo + "KERN" wordmark as a flex-friendly child, with an explicit + * logo diameter (px) so the caller can scale the symbol+wordmark block to fit a + * layout budget. * * @param parent Parent LVGL object (typically a flex container) - * @return Pointer to created container object - */ -lv_obj_t *kern_logo_with_text_inline(lv_obj_t *parent); - -/** - * Same as kern_logo_with_text_inline, but with an explicit logo diameter (px) - * so the caller can scale the symbol+wordmark block to fit a layout budget. + * @param sz Logo diameter in pixels */ lv_obj_t *kern_logo_with_text_inline_sized(lv_obj_t *parent, lv_coord_t sz); @@ -81,11 +65,6 @@ lv_obj_t *kern_logo_with_text_inline_sized(lv_obj_t *parent, lv_coord_t sz); */ void kern_logo_animated(lv_obj_t *parent); -/** - * Example usage function - */ -void kern_logo_example(void); - #ifdef __cplusplus } #endif