From ea596dc94da7eaa5061533ef79d15442eae6a812 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Sat, 18 Mar 2023 20:36:24 +0000 Subject: [PATCH] Initial lockscreen redesign --- applications/services/desktop/desktop.c | 3 +- applications/services/desktop/desktop_i.h | 2 + .../desktop/views/desktop_view_lockscreen.c | 122 ++++++++++++++++++ .../desktop/views/desktop_view_lockscreen.h | 13 ++ applications/services/xtreme/assets.c | 2 + applications/services/xtreme/assets.h | 1 + assets/icons/Interface/Lockscreen.png | Bin 0 -> 5453 bytes 7 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 applications/services/desktop/views/desktop_view_lockscreen.c create mode 100644 applications/services/desktop/views/desktop_view_lockscreen.h create mode 100644 assets/icons/Interface/Lockscreen.png diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 1fe23bb1d..79bd3cfb1 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -165,6 +165,7 @@ Desktop* desktop_alloc() { desktop->debug_view = desktop_debug_alloc(); desktop->hw_mismatch_popup = popup_alloc(); desktop->locked_view = desktop_view_locked_alloc(); + desktop->lockscreen_view = desktop_view_lockscreen_alloc(); desktop->pin_input_view = desktop_view_pin_input_alloc(); desktop->pin_timeout_view = desktop_view_pin_timeout_alloc(); desktop->slideshow_view = desktop_view_slideshow_alloc(); @@ -180,7 +181,7 @@ Desktop* desktop_alloc() { /* locked view (as animation view) attends in 2 scenes: main & locked, * because it has to draw "Unlocked" label on main scene */ desktop->locked_view_stack = view_stack_alloc(); - view_stack_add_view(desktop->locked_view_stack, dolphin_view); + view_stack_add_view(desktop->locked_view_stack, desktop_view_lockscreen_get_view(desktop->lockscreen_view)); view_stack_add_view( desktop->locked_view_stack, desktop_view_locked_get_view(desktop->locked_view)); diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index 822eecc76..2935d0594 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -5,6 +5,7 @@ #include "views/desktop_view_pin_timeout.h" #include "views/desktop_view_pin_input.h" #include "views/desktop_view_locked.h" +#include "views/desktop_view_lockscreen.h" #include "views/desktop_view_main.h" #include "views/desktop_view_lock_menu.h" #include "views/desktop_view_debug.h" @@ -47,6 +48,7 @@ struct Desktop { DesktopLockMenuView* lock_menu; DesktopDebugView* debug_view; DesktopViewLocked* locked_view; + DesktopLockscreenView* lockscreen_view; DesktopMainView* main_view; DesktopViewPinTimeout* pin_timeout_view; DesktopSlideshowView* slideshow_view; diff --git a/applications/services/desktop/views/desktop_view_lockscreen.c b/applications/services/desktop/views/desktop_view_lockscreen.c new file mode 100644 index 000000000..e422c9192 --- /dev/null +++ b/applications/services/desktop/views/desktop_view_lockscreen.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#include + +#include "desktop_view_lockscreen.h" +#include "../desktop_i.h" + +struct DesktopLockscreenView { + View* view; + void* context; +}; + +typedef struct { + LocaleDateFormat date_format; + LocaleTimeFormat time_format; +} DesktopLockscreenViewModel; + +static void desktop_view_lockscreen_draw(Canvas* canvas, void* context) { + DesktopLockscreenViewModel* model = context; + canvas_clear(canvas); + canvas_draw_icon(canvas, 0, 0, XTREME_ASSETS()->I_Lockscreen); + + char time_str[9]; + char date_str[14]; + char meridian_str[3]; + FuriHalRtcDateTime datetime; + furi_hal_rtc_get_datetime(&datetime); + + if(model->time_format == LocaleTimeFormat24h) { + snprintf(time_str, 9, "%.2d:%.2d", datetime.hour, datetime.minute); + } else { + bool pm = datetime.hour > 12; + bool pm12 = datetime.hour >= 12; + snprintf(time_str, 9, "%.2d:%.2d", pm ? datetime.hour - 12 : datetime.hour, datetime.minute); + snprintf(meridian_str, 3, pm12 ? "PM" : "AM"); + } + + if(model->date_format == LocaleDateFormatYMD) { + snprintf(date_str, 14, "%.4d-%.2d-%.2d", datetime.year, datetime.month, datetime.day); + } else if(model->date_format == LocaleDateFormatMDY) { + snprintf(date_str, 14, "%.2d-%.2d-%.4d", datetime.month, datetime.day, datetime.year); + } else { + snprintf(date_str, 14, "%.2d-%.2d-%.4d", datetime.day, datetime.month, datetime.year); + } + + canvas_set_font(canvas, FontBigNumbers); + canvas_draw_str(canvas, 0, 64, time_str); + int meridian_offset = canvas_string_width(canvas, time_str) + 2; + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 48, date_str); + if(model->time_format == LocaleTimeFormat12h) { + canvas_draw_str(canvas, 0 + meridian_offset, 64, meridian_str); + } + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str_aligned(canvas, 64, 6, AlignCenter, AlignCenter, "UP to Unlock"); +} + +static bool desktop_view_lockscreen_input(InputEvent* event, void* context) { + furi_assert(event); + UNUSED(context); + // DesktopLockscreenView* instance = context; + + // DesktopLockscreenViewModel* model = view_get_model(instance->view); + if(event->type == InputTypeShort) { + switch(event->key) { + case InputKeyLeft: + case InputKeyRight: + case InputKeyOk: + case InputKeyBack: + default: + break; + } + } + // view_commit_model(instance->view, update_view); + + return true; +} + +static void desktop_view_lockscreen_enter(void* context) { + DesktopLockscreenView* instance = context; + + DesktopLockscreenViewModel* model = view_get_model(instance->view); + model->time_format = locale_get_time_format(); + model->date_format = locale_get_date_format(); + view_commit_model(instance->view, false); +} + +static void desktop_view_lockscreen_exit(void* context) { + DesktopLockscreenView* instance = context; + UNUSED(instance); + + // DesktopLockscreenViewModel* model = view_get_model(instance->view); + // view_commit_model(instance->view, false); +} + +DesktopLockscreenView* desktop_view_lockscreen_alloc() { + DesktopLockscreenView* instance = malloc(sizeof(DesktopLockscreenView)); + instance->view = view_alloc(); + view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(DesktopLockscreenViewModel)); + view_set_context(instance->view, instance); + view_set_draw_callback(instance->view, (ViewDrawCallback)desktop_view_lockscreen_draw); + view_set_input_callback(instance->view, desktop_view_lockscreen_input); + view_set_enter_callback(instance->view, desktop_view_lockscreen_enter); + view_set_exit_callback(instance->view, desktop_view_lockscreen_exit); + + return instance; +} + +void desktop_view_lockscreen_free(DesktopLockscreenView* instance) { + furi_assert(instance); + + view_free(instance->view); + free(instance); +} + +View* desktop_view_lockscreen_get_view(DesktopLockscreenView* instance) { + furi_assert(instance); + return instance->view; +} diff --git a/applications/services/desktop/views/desktop_view_lockscreen.h b/applications/services/desktop/views/desktop_view_lockscreen.h new file mode 100644 index 000000000..64e9ae7c9 --- /dev/null +++ b/applications/services/desktop/views/desktop_view_lockscreen.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#include "desktop_events.h" + +typedef struct DesktopLockscreenView DesktopLockscreenView; + +DesktopLockscreenView* desktop_view_lockscreen_alloc(); + +void desktop_view_lockscreen_free(DesktopLockscreenView* main_view); + +View* desktop_view_lockscreen_get_view(DesktopLockscreenView* main_view); diff --git a/applications/services/xtreme/assets.c b/applications/services/xtreme/assets.c index ce73e4f87..fc39f18f5 100644 --- a/applications/services/xtreme/assets.c +++ b/applications/services/xtreme/assets.c @@ -93,6 +93,7 @@ void swap(XtremeAssets* x, FuriString* p, File* f) { icon(&x->I_DolphinWait_61x59, "iButton/DolphinWait_61x59", p, f); icon(&x->I_iButtonDolphinVerySuccess_108x52, "iButton/iButtonDolphinVerySuccess_108x52", p, f); icon(&x->I_DolphinReadingSuccess_59x63, "Infrared/DolphinReadingSuccess_59x63", p, f); + icon(&x->I_Lockscreen, "Interface/Lockscreen", p, f); icon(&x->I_NFC_dolphin_emulation_47x61, "NFC/NFC_dolphin_emulation_47x61", p, f); icon(&x->I_passport_bad_46x49, "Passport/passport_bad_46x49", p, f); icon(&x->I_passport_DB, "Passport/passport_DB", p, f); @@ -123,6 +124,7 @@ void XTREME_ASSETS_LOAD() { xtreme_assets->I_DolphinWait_61x59 = &I_DolphinWait_61x59; xtreme_assets->I_iButtonDolphinVerySuccess_108x52 = &I_iButtonDolphinVerySuccess_108x52; xtreme_assets->I_DolphinReadingSuccess_59x63 = &I_DolphinReadingSuccess_59x63; + xtreme_assets->I_Lockscreen = &I_Lockscreen; xtreme_assets->I_NFC_dolphin_emulation_47x61 = &I_NFC_dolphin_emulation_47x61; xtreme_assets->I_passport_bad_46x49 = &I_passport_bad_46x49; xtreme_assets->I_passport_DB = &I_passport_DB; diff --git a/applications/services/xtreme/assets.h b/applications/services/xtreme/assets.h index f987fd475..5e96f99f7 100644 --- a/applications/services/xtreme/assets.h +++ b/applications/services/xtreme/assets.h @@ -20,6 +20,7 @@ typedef struct { const Icon* I_DolphinWait_61x59; const Icon* I_iButtonDolphinVerySuccess_108x52; const Icon* I_DolphinReadingSuccess_59x63; + const Icon* I_Lockscreen; const Icon* I_NFC_dolphin_emulation_47x61; const Icon* I_passport_bad_46x49; const Icon* I_passport_DB; diff --git a/assets/icons/Interface/Lockscreen.png b/assets/icons/Interface/Lockscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..c9aa8bcd7e906e0fcd650f1437884709a7b2ee28 GIT binary patch literal 5453 zcmeHLdsGuw8Xu|x2C1l}r7qna;seo6l9|bKBp65nWF^W1iqE5y$qkH>2T6E{)`M8J zisHK>;HoPqDoZQYM^P7iP^zM$o|d93C|b1^U)593@x|UGfKc(QoU`s<(c>b#IfFR}f_Q5pRWb0M2``0PFZh4k?`|->9nFZFWRIcKP>a=UV3Po9 zpJM?iNM{WQl77h;eR)8y0MF+;maRiqKKk09pJ2EUda6IiaCYeEAtl+Rp5N3xay#&T zm|K17nPIo|tGJ7H4bbLL+~FT5&-^l};x@WhF?}S6BFCg#YZV zC%g)0gx^>?H)7LfI_}sPC%ydKf2de*J^$kAqHRUKcf2xureA(pe_wpWwl^)e7`K*v z|7ipAq^j}< `3)^Bb8<%>6Z-)Jlte%1SW%H;mO?qf0##O-rdsf^Yrm2J*I7YaUG zEss2|@UNN?o6Yq-n(CAMee|a0e{gg5an!{=vldPKB#QSUYq+;&S@yQ8Q!EddJ$J4) zmF!-)8}*!@d9Yj>R35psWh@8N1xxQ$ADX-JP+Def3329*2FWw!Z;Xqn`8mF-A-*^M zxo4B-$r|G3&>-)|hbb$O8TXrlPq+MgGo!#J_4EAVL|;R$_@Vp5n(anQLtsu>S;@f7 zgU09DLz^N>NBy}XnfL9d4{C}xo~aoWv9v1YqfygqPHhhl*80baHvP7!pnBvj?Cg|% zXD>au!SDCcjGqZsm)qw=oBdR+*)h!LqD~R}Y&mz5HX2o$tpFABgggPJPG?gIZU_erw(1R3 zj4Hep0=~()iFUh%;`7te(s*ek&umTL<1(3yFCh2?fk6q(HpgVA(=n56hy%ifp#nC> z%3AEK*@QYUX`MO6F6VOLJlbZT(W2G1!<%faEI>Z^>9mE9^8|dOk>63nW>=>|kXD1b z)Ud_D8s*0Tn>oeG0Cg%b*@tw7hykyBdJ70B-U&d@v>RYau_ihB&@+6H1dMPk8#Ej5 zWOIZ@8{Mwq;4pzTTAW%iTAd^vp|D z8|zMND5cd>Dl?Pf@JpkTbKwY2&*~{bm_!(^RE7#AN;QtFl~SQ7Tt$XTlp-=*9ZrOG zP}i7jcG|>%Hgy)N>aTgfx!8DO^H{q@x5RC2%>}E^W5PnaxRZu7d~E zVQxE^7Iq9hZKvDepfX9}5KchhI3<8^f{t*|A=WVGzezj#0~+kgtw`2pH(Td8hg?k~ z79_jgT(3#2vs<93v+gOHaXD`_B7fGLK7hCa&D-jS)l4s_VdVY0f$;28lPIr!~oj@B%Oe7?(HYd?6G zOQ2}aBHiM*hpryFy2U`ZgnP29hpuih&@JJf?E0V4#d-DB0+`@QJPm%6_+{uFJ->R*XHa_@KH%vup>tBD*#~xM{TSG-}zon!t-|yT(*C) z+wQrJgqH6V@#7`cv@=IaM!{Hr<^Yj$!Rn;>ReI5KkxN@Y^yps->0Db+_WNO?}XCa(FMh;{A6DL8WOe2@_c2q zrT$EC*pj`^u72}j;g*uJ48w%qiw+<66oo`gzBwiEVAko2wN^km=dG8jeqN3%(cLh@`x~l|_!e%$sxY*YE1V z%%I=ye4Lr*ztxx(FnF$8iTCXbBlc+(gBGm`s~s6MZ?H!$n*U^^Ww>uY-ZMf0EX