From 2bdc34274f98d5dddb0e79e514940d6fe1d016d9 Mon Sep 17 00:00:00 2001 From: Kowalski Dragon Date: Mon, 19 Dec 2022 22:43:32 +0100 Subject: [PATCH] Clock v1 (#1750) --- applications/plugins/clock/application.fam | 10 ++ applications/plugins/clock/clock.png | Bin 0 -> 1896 bytes applications/plugins/clock/clock_app.c | 136 +++++++++++++++++++++ applications/services/locale/locale.c | 3 + 4 files changed, 149 insertions(+) create mode 100644 applications/plugins/clock/application.fam create mode 100644 applications/plugins/clock/clock.png create mode 100644 applications/plugins/clock/clock_app.c diff --git a/applications/plugins/clock/application.fam b/applications/plugins/clock/application.fam new file mode 100644 index 00000000..590f5dfe --- /dev/null +++ b/applications/plugins/clock/application.fam @@ -0,0 +1,10 @@ +App( + appid="clock", + name="Clock", + apptype=FlipperAppType.PLUGIN, + entry_point="clock_app", + requires=["gui"], + stack_size=2 * 1024, + fap_icon="clock.png", + fap_category="Tools", +) diff --git a/applications/plugins/clock/clock.png b/applications/plugins/clock/clock.png new file mode 100644 index 0000000000000000000000000000000000000000..0d96df1020317ef6df0652bc6a0b0b5c1190fa59 GIT binary patch literal 1896 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#IhXQ2>tmIipR1RclAn~S zSCLx)lxJYDv9BmdOwLX%QAkQn&&;z`dcS+Wl0s&Rtx~wDuYqrYb81GWM^#a3aFt(3 za#eP+Wr~u$9hXgo70`g()RIJnirk#MVyg;UC9t_xKsHENUr7P1q$Jx`DZ)2E!8yMu zRl!uxRL?-kj!VI&C?(A*$i)q+8OXC$$|xx*u+rBrFE7_CH`dE9O4m2Ew6xSWFw!?N z(gmu}Ew0QfNvzP#D^>;>0WrfRwK%ybv!En1KTiQQ?NYItfzCc^Z* zVyO3l0ih3)(KpmH&_`BYkda@KU!0L&0Cy3J9=J4y#*)l59QJ@@Fq8v>54#N&i3Qjc z`}*Qno|}u}jp7p5GGIVJ0~N&!Fbj%9DhpEegHnt0ON)|IUCUDQN|eDN0SXr@=lq=f zqF`XsNVQcmLXVw6UXlT~93c^&nSw43@?cIW zD20UPWdei52y8D{O9VpBR>|B*AIX|XtWv;8v+@O|?v%umM3=-8pi7MmfT`2aNY}_9 z#K6?b#K_9fRNKJP$^a57VDum{2EA0%6xpH@#=h%wQUZYC^la6WZH#5$!TUq(|>phQ6 zq1(EIr1y*cVa=JkHOR$l+9owKpYxT*!OAm>t-sg2`+l!@*Y}tWuA95EuKaX7`}C`a z#gln+XP2ArNjTowEw?MVYay?{uW!IryZ0+MK3aQzRp{S4`>)OMkm9;x!o{ySYo55A z@Vtn#*<$ZGc2DuqQLIsWbM=Vq<%rjUAd-T>6dHXx3uMISzG$D99VU67I;J!Gca%qgD@k*tT_@u zK^IRK#}J9Bt^J;S35`&tSQ2 tcwMJ+VNB(c2WNkm|NQ;lbiu<-j5A!_Z&kb&`3|ZeJzf1=);T3K0RUC#hDiVb literal 0 HcmV?d00001 diff --git a/applications/plugins/clock/clock_app.c b/applications/plugins/clock/clock_app.c new file mode 100644 index 00000000..e196f0d2 --- /dev/null +++ b/applications/plugins/clock/clock_app.c @@ -0,0 +1,136 @@ +#include +#include + +#include +#include + +typedef enum { + ClockEventTypeTick, + ClockEventTypeKey, +} ClockEventType; + +typedef struct { + ClockEventType type; + InputEvent input; +} ClockEvent; + +typedef struct { + FuriString* buffer; + FuriHalRtcDateTime datetime; + LocaleTimeFormat timeformat; + LocaleDateFormat dateformat; +} ClockData; + +typedef struct { + FuriMutex* mutex; + FuriMessageQueue* queue; + ClockData* data; +} Clock; + +static void clock_input_callback(InputEvent* input_event, FuriMessageQueue* queue) { + furi_assert(queue); + ClockEvent event = {.type = ClockEventTypeKey, .input = *input_event}; + furi_message_queue_put(queue, &event, FuriWaitForever); +} + +static void clock_render_callback(Canvas* canvas, void* ctx) { + Clock* clock = ctx; + if(furi_mutex_acquire(clock->mutex, 200) != FuriStatusOk) { + return; + } + + ClockData* data = clock->data; + + canvas_set_font(canvas, FontBigNumbers); + locale_format_time(data->buffer, &data->datetime, data->timeformat, true); + canvas_draw_str_aligned( + canvas, 64, 28, AlignCenter, AlignCenter, furi_string_get_cstr(data->buffer)); + + // Special case to cover missing glyphs in FontBigNumbers + if(data->timeformat == LocaleTimeFormat12h) { + size_t time_width = canvas_string_width(canvas, furi_string_get_cstr(data->buffer)); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned( + canvas, + 64 + (time_width / 2) - 10, + 31, + AlignLeft, + AlignCenter, + (data->datetime.hour > 12) ? "AM" : "PM"); + } + + canvas_set_font(canvas, FontSecondary); + locale_format_date(data->buffer, &data->datetime, data->dateformat, "/"); + canvas_draw_str_aligned( + canvas, 64, 42, AlignCenter, AlignTop, furi_string_get_cstr(data->buffer)); + + furi_mutex_release(clock->mutex); +} + +static void clock_tick(void* ctx) { + furi_assert(ctx); + FuriMessageQueue* queue = ctx; + ClockEvent event = {.type = ClockEventTypeTick}; + // It's OK to loose this event if system overloaded + furi_message_queue_put(queue, &event, 0); +} + +int32_t clock_app(void* p) { + UNUSED(p); + Clock* clock = malloc(sizeof(Clock)); + clock->data = malloc(sizeof(ClockData)); + clock->data->buffer = furi_string_alloc(); + + clock->queue = furi_message_queue_alloc(8, sizeof(ClockEvent)); + clock->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + + furi_hal_rtc_get_datetime(&clock->data->datetime); + clock->data->timeformat = locale_get_time_format(); + clock->data->dateformat = locale_get_date_format(); + + // Set ViewPort callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, clock_render_callback, clock); + view_port_input_callback_set(view_port, clock_input_callback, clock->queue); + + FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, clock->queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + furi_timer_start(timer, 100); + + // Main loop + ClockEvent event; + for(bool processing = true; processing;) { + furi_check(furi_message_queue_get(clock->queue, &event, FuriWaitForever) == FuriStatusOk); + furi_mutex_acquire(clock->mutex, FuriWaitForever); + if(event.type == ClockEventTypeKey) { + if(event.input.type == InputTypeShort && event.input.key == InputKeyBack) { + processing = false; + } + } else if(event.type == ClockEventTypeTick) { + furi_hal_rtc_get_datetime(&clock->data->datetime); + } + + furi_mutex_release(clock->mutex); + view_port_update(view_port); + } + + furi_timer_free(timer); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_record_close(RECORD_GUI); + + furi_message_queue_free(clock->queue); + furi_mutex_free(clock->mutex); + + furi_string_free(clock->data->buffer); + + free(clock->data); + free(clock); + + return 0; +} \ No newline at end of file diff --git a/applications/services/locale/locale.c b/applications/services/locale/locale.c index 07f56b1b..e8b6a9fc 100644 --- a/applications/services/locale/locale.c +++ b/applications/services/locale/locale.c @@ -51,6 +51,9 @@ void locale_format_time( } else { am_pm = 1; } + if(hours == 0) { + hours = 12; + } } if(show_seconds) {