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 000000000..c9aa8bcd7 Binary files /dev/null and b/assets/icons/Interface/Lockscreen.png differ