mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-14 09:28:36 -07:00
New Locale Settings API & Fix for long filenames
This commit is contained in:
11
applications/debug/locale_test/application.fam
Normal file
11
applications/debug/locale_test/application.fam
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
App(
|
||||||
|
appid="locale_test",
|
||||||
|
name="Locale Test",
|
||||||
|
apptype=FlipperAppType.DEBUG,
|
||||||
|
entry_point="locale_test_app",
|
||||||
|
cdefines=["APP_LOCALE"],
|
||||||
|
requires=["gui", "locale"],
|
||||||
|
stack_size=2 * 1024,
|
||||||
|
order=70,
|
||||||
|
fap_category="Debug",
|
||||||
|
)
|
||||||
102
applications/debug/locale_test/locale_test.c
Normal file
102
applications/debug/locale_test/locale_test.c
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include <furi.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
#include <gui/elements.h>
|
||||||
|
#include <gui/view_dispatcher.h>
|
||||||
|
#include <gui/modules/dialog_ex.h>
|
||||||
|
#include <locale/locale.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Gui* gui;
|
||||||
|
ViewDispatcher* view_dispatcher;
|
||||||
|
View* view;
|
||||||
|
} LocaleTestApp;
|
||||||
|
|
||||||
|
static void locale_test_view_draw_callback(Canvas* canvas, void* _model) {
|
||||||
|
UNUSED(_model);
|
||||||
|
|
||||||
|
// Prepare canvas
|
||||||
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
|
||||||
|
FuriString* tmp_string = furi_string_alloc();
|
||||||
|
|
||||||
|
float temp = 25.3f;
|
||||||
|
LocaleMeasurementUnit units = locale_get_measurement_unit();
|
||||||
|
if(units == LocaleMeasurementUnitMetric) {
|
||||||
|
furi_string_printf(tmp_string, "Temp: %5.1fC", (double)temp);
|
||||||
|
} else {
|
||||||
|
temp = locale_celsius_to_fahrenheit(temp);
|
||||||
|
furi_string_printf(tmp_string, "Temp: %5.1fF", (double)temp);
|
||||||
|
}
|
||||||
|
canvas_draw_str(canvas, 0, 10, furi_string_get_cstr(tmp_string));
|
||||||
|
|
||||||
|
FuriHalRtcDateTime datetime;
|
||||||
|
furi_hal_rtc_get_datetime(&datetime);
|
||||||
|
|
||||||
|
locale_format_time(tmp_string, &datetime, locale_get_time_format(), false);
|
||||||
|
canvas_draw_str(canvas, 0, 25, furi_string_get_cstr(tmp_string));
|
||||||
|
|
||||||
|
locale_format_date(tmp_string, &datetime, locale_get_date_format(), "/");
|
||||||
|
canvas_draw_str(canvas, 0, 40, furi_string_get_cstr(tmp_string));
|
||||||
|
|
||||||
|
furi_string_free(tmp_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool locale_test_view_input_callback(InputEvent* event, void* context) {
|
||||||
|
UNUSED(event);
|
||||||
|
UNUSED(context);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t locale_test_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
|
return VIEW_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LocaleTestApp* locale_test_alloc() {
|
||||||
|
LocaleTestApp* app = malloc(sizeof(LocaleTestApp));
|
||||||
|
|
||||||
|
// Gui
|
||||||
|
app->gui = furi_record_open(RECORD_GUI);
|
||||||
|
|
||||||
|
// View dispatcher
|
||||||
|
app->view_dispatcher = view_dispatcher_alloc();
|
||||||
|
view_dispatcher_enable_queue(app->view_dispatcher);
|
||||||
|
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||||
|
|
||||||
|
// Views
|
||||||
|
app->view = view_alloc();
|
||||||
|
view_set_draw_callback(app->view, locale_test_view_draw_callback);
|
||||||
|
view_set_input_callback(app->view, locale_test_view_input_callback);
|
||||||
|
|
||||||
|
view_set_previous_callback(app->view, locale_test_exit);
|
||||||
|
view_dispatcher_add_view(app->view_dispatcher, 0, app->view);
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, 0);
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void locale_test_free(LocaleTestApp* app) {
|
||||||
|
furi_assert(app);
|
||||||
|
|
||||||
|
// Free views
|
||||||
|
view_dispatcher_remove_view(app->view_dispatcher, 0);
|
||||||
|
|
||||||
|
view_free(app->view);
|
||||||
|
view_dispatcher_free(app->view_dispatcher);
|
||||||
|
|
||||||
|
// Close gui record
|
||||||
|
furi_record_close(RECORD_GUI);
|
||||||
|
app->gui = NULL;
|
||||||
|
|
||||||
|
// Free rest
|
||||||
|
free(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t locale_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
|
LocaleTestApp* app = locale_test_alloc();
|
||||||
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
|
locale_test_free(app);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -532,21 +532,21 @@ void elements_bubble_str(
|
|||||||
canvas_draw_line(canvas, x2, y2, x3, y3);
|
canvas_draw_line(canvas, x2, y2, x3, y3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width) {
|
|
||||||
|
void elements_string_fit_width_trunc(Canvas* canvas, FuriString* string, uint8_t width) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
furi_assert(string);
|
furi_assert(string);
|
||||||
|
|
||||||
uint16_t len_px = canvas_string_width(canvas, furi_string_get_cstr(string));
|
uint16_t len_px = canvas_string_width(canvas, furi_string_get_cstr(string));
|
||||||
if(len_px > width) {
|
if(len_px > width) {
|
||||||
width -= canvas_string_width(canvas, "...");
|
|
||||||
do {
|
do {
|
||||||
furi_string_left(string, furi_string_size(string) - 1);
|
furi_string_left(string, furi_string_size(string) - 1);
|
||||||
len_px = canvas_string_width(canvas, furi_string_get_cstr(string));
|
len_px = canvas_string_width(canvas, furi_string_get_cstr(string));
|
||||||
} while(len_px > width);
|
} while(len_px > width);
|
||||||
furi_string_cat(string, "...");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void elements_text_box(
|
void elements_text_box(
|
||||||
Canvas* canvas,
|
Canvas* canvas,
|
||||||
uint8_t x,
|
uint8_t x,
|
||||||
|
|||||||
@@ -192,6 +192,15 @@ void elements_bubble_str(
|
|||||||
*/
|
*/
|
||||||
void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width);
|
void elements_string_fit_width(Canvas* canvas, FuriString* string, uint8_t width);
|
||||||
|
|
||||||
|
/** Trim string buffer to fit width in pixels. If the string is longer it truncates without ellipsis (...)
|
||||||
|
*
|
||||||
|
* @param canvas Canvas instance
|
||||||
|
* @param string string to trim
|
||||||
|
* @param width max width
|
||||||
|
*/
|
||||||
|
void elements_string_fit_width_trunc(Canvas* canvas, FuriString* string, uint8_t width);
|
||||||
|
|
||||||
|
|
||||||
/** Draw text box element
|
/** Draw text box element
|
||||||
*
|
*
|
||||||
* @param canvas Canvas instance
|
* @param canvas Canvas instance
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
#include <core/common_defines.h>
|
#include <core/common_defines.h>
|
||||||
#include <core/log.h>
|
#include <core/log.h>
|
||||||
#include "furi_hal_resources.h"
|
#include "furi_hal_resources.h"
|
||||||
#include "m-string.h"
|
|
||||||
#include "m-algo.h"
|
|
||||||
#include <m-array.h>
|
#include <m-array.h>
|
||||||
#include <gui/elements.h>
|
#include <gui/elements.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
@@ -72,30 +70,14 @@ static void BrowserItem_t_clear(BrowserItem_t* obj) {
|
|||||||
free(obj->custom_icon_data);
|
free(obj->custom_icon_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ARRAY_DEF(
|
||||||
|
|
||||||
static int BrowserItem_t_cmp(const BrowserItem_t* a, const BrowserItem_t* b) {
|
items_array,
|
||||||
// Back indicator comes before everything, then folders, then all other files.
|
BrowserItem_t,
|
||||||
if((a->type == BrowserItemTypeBack) ||
|
(INIT(API_2(BrowserItem_t_init)),
|
||||||
(a->type == BrowserItemTypeFolder && b->type != BrowserItemTypeFolder &&
|
SET(API_6(BrowserItem_t_set)),
|
||||||
b->type != BrowserItemTypeBack)) {
|
INIT_SET(API_6(BrowserItem_t_init_set)),
|
||||||
return -1;
|
CLEAR(API_2(BrowserItem_t_clear))))
|
||||||
}
|
|
||||||
|
|
||||||
return furi_string_cmp(a->path, b->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define M_OPL_BrowserItem_t() \
|
|
||||||
(INIT(API_2(BrowserItem_t_init)), \
|
|
||||||
SET(API_6(BrowserItem_t_set)), \
|
|
||||||
INIT_SET(API_6(BrowserItem_t_init_set)), \
|
|
||||||
CLEAR(API_2(BrowserItem_t_clear)), \
|
|
||||||
CMP(API_6(BrowserItem_t_cmp)), \
|
|
||||||
SWAP(M_SWAP_DEFAULT), \
|
|
||||||
EQUAL(API_6(M_EQUAL_DEFAULT)))
|
|
||||||
|
|
||||||
ARRAY_DEF(items_array, BrowserItem_t)
|
|
||||||
|
|
||||||
ALGO_DEF(items_array, ARRAY_OPLIST(items_array, M_OPL_BrowserItem_t()))
|
|
||||||
|
|
||||||
struct FileBrowser {
|
struct FileBrowser {
|
||||||
View* view;
|
View* view;
|
||||||
@@ -112,6 +94,8 @@ struct FileBrowser {
|
|||||||
FileBrowserLoadItemCallback item_callback;
|
FileBrowserLoadItemCallback item_callback;
|
||||||
void* item_context;
|
void* item_context;
|
||||||
|
|
||||||
|
FuriTimer* timer;
|
||||||
|
|
||||||
FuriString* result_path;
|
FuriString* result_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,6 +110,8 @@ typedef struct {
|
|||||||
int32_t array_offset;
|
int32_t array_offset;
|
||||||
int32_t list_offset;
|
int32_t list_offset;
|
||||||
|
|
||||||
|
FuriString* current_filename;
|
||||||
|
|
||||||
const Icon* file_icon;
|
const Icon* file_icon;
|
||||||
bool hide_ext;
|
bool hide_ext;
|
||||||
} FileBrowserModel;
|
} FileBrowserModel;
|
||||||
@@ -139,6 +125,9 @@ static const Icon* BrowserItemIcons[] = {
|
|||||||
|
|
||||||
static void file_browser_view_draw_callback(Canvas* canvas, void* _model);
|
static void file_browser_view_draw_callback(Canvas* canvas, void* _model);
|
||||||
static bool file_browser_view_input_callback(InputEvent* event, void* context);
|
static bool file_browser_view_input_callback(InputEvent* event, void* context);
|
||||||
|
static void file_browser_animate_filename_callback(void* context);
|
||||||
|
|
||||||
|
static const char* file_browser_get_selected_filename(FileBrowserModel* model);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
browser_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root);
|
browser_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root);
|
||||||
@@ -157,9 +146,17 @@ FileBrowser* file_browser_alloc(FuriString* result_path) {
|
|||||||
view_set_input_callback(browser->view, file_browser_view_input_callback);
|
view_set_input_callback(browser->view, file_browser_view_input_callback);
|
||||||
|
|
||||||
browser->result_path = result_path;
|
browser->result_path = result_path;
|
||||||
|
browser->timer =
|
||||||
|
furi_timer_alloc(file_browser_animate_filename_callback, FuriTimerTypePeriodic, browser);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, FileBrowserModel * model, { items_array_init(model->items); }, false);
|
browser->view,
|
||||||
|
FileBrowserModel * model,
|
||||||
|
{
|
||||||
|
items_array_init(model->items);
|
||||||
|
model->current_filename = furi_string_alloc();
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
@@ -168,9 +165,16 @@ void file_browser_free(FileBrowser* browser) {
|
|||||||
furi_assert(browser);
|
furi_assert(browser);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, FileBrowserModel * model, { items_array_clear(model->items); }, false);
|
browser->view,
|
||||||
|
FileBrowserModel * model,
|
||||||
|
{
|
||||||
|
items_array_clear(model->items);
|
||||||
|
furi_string_free(model->current_filename);
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
|
||||||
view_free(browser->view);
|
view_free(browser->view);
|
||||||
|
furi_timer_free(browser->timer);
|
||||||
free(browser);
|
free(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,8 +236,10 @@ void file_browser_stop(FileBrowser* browser) {
|
|||||||
model->item_idx = 0;
|
model->item_idx = 0;
|
||||||
model->array_offset = 0;
|
model->array_offset = 0;
|
||||||
model->list_offset = 0;
|
model->list_offset = 0;
|
||||||
|
furi_string_set(model->current_filename, "");
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
|
furi_timer_stop(browser->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_browser_set_callback(FileBrowser* browser, FileBrowserCallback callback, void* context) {
|
void file_browser_set_callback(FileBrowser* browser, FileBrowserCallback callback, void* context) {
|
||||||
@@ -336,6 +342,7 @@ static void
|
|||||||
model->is_root = is_root;
|
model->is_root = is_root;
|
||||||
model->list_loading = true;
|
model->list_loading = true;
|
||||||
model->folder_loading = false;
|
model->folder_loading = false;
|
||||||
|
furi_string_set(model->current_filename, file_browser_get_selected_filename(model));
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
browser_update_offset(browser);
|
browser_update_offset(browser);
|
||||||
@@ -420,13 +427,7 @@ static void
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view,
|
browser->view, FileBrowserModel * model, { model->list_loading = false; }, true);
|
||||||
FileBrowserModel * model,
|
|
||||||
{
|
|
||||||
items_array_sort(model->items);
|
|
||||||
model->list_loading = false;
|
|
||||||
},
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,8 +493,17 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) {
|
|||||||
furi_string_set(filename, ". .");
|
furi_string_set(filename, ". .");
|
||||||
}
|
}
|
||||||
|
|
||||||
elements_string_fit_width(
|
uint8_t frame_width = (show_scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX);
|
||||||
canvas, filename, (show_scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX));
|
|
||||||
|
bool is_long_filename = canvas_string_width(canvas, furi_string_get_cstr(filename)) >
|
||||||
|
frame_width;
|
||||||
|
|
||||||
|
if(is_long_filename && model->item_idx == idx) {
|
||||||
|
furi_string_set(filename, model->current_filename);
|
||||||
|
elements_string_fit_width_trunc(canvas, filename, frame_width);
|
||||||
|
} else {
|
||||||
|
elements_string_fit_width(canvas, filename, frame_width);
|
||||||
|
}
|
||||||
|
|
||||||
if(model->item_idx == idx) {
|
if(model->item_idx == idx) {
|
||||||
browser_draw_frame(canvas, i, show_scrollbar);
|
browser_draw_frame(canvas, i, show_scrollbar);
|
||||||
@@ -538,6 +548,36 @@ static void file_browser_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void file_browser_animate_filename_callback(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
FileBrowser* browser = context;
|
||||||
|
with_view_model(
|
||||||
|
browser->view,
|
||||||
|
FileBrowserModel * model,
|
||||||
|
{
|
||||||
|
FuriString* old_filename;
|
||||||
|
old_filename = furi_string_alloc();
|
||||||
|
furi_string_set(old_filename, model->current_filename);
|
||||||
|
furi_string_left(old_filename, 1);
|
||||||
|
furi_string_right(model->current_filename, 1);
|
||||||
|
furi_string_cat(model->current_filename, old_filename);
|
||||||
|
furi_string_free(old_filename);
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* file_browser_get_selected_filename(FileBrowserModel* model) {
|
||||||
|
furi_assert(model);
|
||||||
|
BrowserItem_t* selected_item = NULL;
|
||||||
|
|
||||||
|
if(browser_is_item_in_array(model, model->item_idx)) {
|
||||||
|
selected_item = items_array_get(model->items, model->item_idx - model->array_offset);
|
||||||
|
return furi_string_get_cstr(selected_item->display_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
||||||
FileBrowser* browser = context;
|
FileBrowser* browser = context;
|
||||||
furi_assert(browser);
|
furi_assert(browser);
|
||||||
@@ -558,6 +598,10 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
|||||||
if(event->key == InputKeyUp) {
|
if(event->key == InputKeyUp) {
|
||||||
model->item_idx =
|
model->item_idx =
|
||||||
((model->item_idx - 1) + model->item_cnt) % model->item_cnt;
|
((model->item_idx - 1) + model->item_cnt) % model->item_cnt;
|
||||||
|
furi_string_set(
|
||||||
|
model->current_filename, file_browser_get_selected_filename(model));
|
||||||
|
furi_string_cat(model->current_filename, " ");
|
||||||
|
furi_timer_start(browser->timer, 250);
|
||||||
if(browser_is_list_load_required(model)) {
|
if(browser_is_list_load_required(model)) {
|
||||||
model->list_loading = true;
|
model->list_loading = true;
|
||||||
int32_t load_offset = CLAMP(
|
int32_t load_offset = CLAMP(
|
||||||
@@ -569,6 +613,10 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
|
|||||||
}
|
}
|
||||||
} else if(event->key == InputKeyDown) {
|
} else if(event->key == InputKeyDown) {
|
||||||
model->item_idx = (model->item_idx + 1) % model->item_cnt;
|
model->item_idx = (model->item_idx + 1) % model->item_cnt;
|
||||||
|
furi_string_set(
|
||||||
|
model->current_filename, file_browser_get_selected_filename(model));
|
||||||
|
furi_string_cat(model->current_filename, " ");
|
||||||
|
furi_timer_start(browser->timer, 250);
|
||||||
if(browser_is_list_load_required(model)) {
|
if(browser_is_list_load_required(model)) {
|
||||||
model->list_loading = true;
|
model->list_loading = true;
|
||||||
int32_t load_offset = CLAMP(
|
int32_t load_offset = CLAMP(
|
||||||
|
|||||||
9
applications/services/locale/application.fam
Normal file
9
applications/services/locale/application.fam
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
App(
|
||||||
|
appid="locale",
|
||||||
|
name="LocaleSrv",
|
||||||
|
apptype=FlipperAppType.STARTUP,
|
||||||
|
entry_point="locale_on_system_start",
|
||||||
|
cdefines=["SRV_LOCALE"],
|
||||||
|
order=90,
|
||||||
|
sdk_headers=["locale.h"],
|
||||||
|
)
|
||||||
109
applications/services/locale/locale.c
Normal file
109
applications/services/locale/locale.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#include "locale.h"
|
||||||
|
|
||||||
|
#define TAG "LocaleSrv"
|
||||||
|
|
||||||
|
LocaleMeasurementUnit locale_get_measurement_unit(void) {
|
||||||
|
return furi_hal_rtc_get_locale_units();
|
||||||
|
}
|
||||||
|
|
||||||
|
void locale_set_measurement_unit(LocaleMeasurementUnit format) {
|
||||||
|
furi_hal_rtc_set_locale_units(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocaleTimeFormat locale_get_time_format(void) {
|
||||||
|
return furi_hal_rtc_get_locale_timeformat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void locale_set_time_format(LocaleTimeFormat format) {
|
||||||
|
furi_hal_rtc_set_locale_timeformat(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocaleDateFormat locale_get_date_format(void) {
|
||||||
|
return furi_hal_rtc_get_locale_dateformat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void locale_set_date_format(LocaleDateFormat format) {
|
||||||
|
furi_hal_rtc_set_locale_dateformat(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
float locale_fahrenheit_to_celsius(float temp_f) {
|
||||||
|
return (temp_f - 32.f) / 1.8f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float locale_celsius_to_fahrenheit(float temp_c) {
|
||||||
|
return (temp_c * 1.8f + 32.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void locale_format_time(
|
||||||
|
FuriString* out_str,
|
||||||
|
FuriHalRtcDateTime* datetime,
|
||||||
|
LocaleTimeFormat format,
|
||||||
|
bool show_seconds) {
|
||||||
|
furi_assert(out_str);
|
||||||
|
furi_assert(datetime);
|
||||||
|
|
||||||
|
uint8_t hours = datetime->hour;
|
||||||
|
uint8_t am_pm = 0;
|
||||||
|
if(format == LocaleTimeFormat12h) {
|
||||||
|
if(hours > 12) {
|
||||||
|
hours -= 12;
|
||||||
|
am_pm = 2;
|
||||||
|
} else {
|
||||||
|
am_pm = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(show_seconds) {
|
||||||
|
furi_string_printf(out_str, "%02u:%02u:%02u", hours, datetime->minute, datetime->second);
|
||||||
|
} else {
|
||||||
|
furi_string_printf(out_str, "%02u:%02u", hours, datetime->minute);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(am_pm > 0) {
|
||||||
|
furi_string_cat_printf(out_str, " %s", (am_pm == 1) ? ("AM") : ("PM"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void locale_format_date(
|
||||||
|
FuriString* out_str,
|
||||||
|
FuriHalRtcDateTime* datetime,
|
||||||
|
LocaleDateFormat format,
|
||||||
|
char* separator) {
|
||||||
|
furi_assert(out_str);
|
||||||
|
furi_assert(datetime);
|
||||||
|
furi_assert(separator);
|
||||||
|
|
||||||
|
if(format == LocaleDateFormatDMY) {
|
||||||
|
furi_string_printf(
|
||||||
|
out_str,
|
||||||
|
"%02u%s%02u%s%04u",
|
||||||
|
datetime->day,
|
||||||
|
separator,
|
||||||
|
datetime->month,
|
||||||
|
separator,
|
||||||
|
datetime->year);
|
||||||
|
} else if(format == LocaleDateFormatMDY) {
|
||||||
|
furi_string_printf(
|
||||||
|
out_str,
|
||||||
|
"%02u%s%02u%s%04u",
|
||||||
|
datetime->month,
|
||||||
|
separator,
|
||||||
|
datetime->day,
|
||||||
|
separator,
|
||||||
|
datetime->year);
|
||||||
|
} else {
|
||||||
|
furi_string_printf(
|
||||||
|
out_str,
|
||||||
|
"%04u%s%02u%s%02u",
|
||||||
|
datetime->year,
|
||||||
|
separator,
|
||||||
|
datetime->month,
|
||||||
|
separator,
|
||||||
|
datetime->day);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t locale_on_system_start(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
53
applications/services/locale/locale.h
Normal file
53
applications/services/locale/locale.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <furi.h>
|
||||||
|
#include <furi_hal.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LocaleMeasurementUnitMetric = 0, /**< Meric mesurement units */
|
||||||
|
LocaleMeasurementUnitImperial, /**< Imperial mesurement units */
|
||||||
|
} LocaleMeasurementUnit;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LocaleTimeFormat24h = 0, /**< 24-hour format */
|
||||||
|
LocaleTimeFormat12h, /**< 12-hour format */
|
||||||
|
} LocaleTimeFormat;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LocaleDateFormatDMY = 0, /**< Day/Month/Year */
|
||||||
|
LocaleDateFormatMDY, /**< Month/Day/Year */
|
||||||
|
LocaleDateFormatYMD, /**< Year/Month/Day */
|
||||||
|
} LocaleDateFormat;
|
||||||
|
|
||||||
|
LocaleMeasurementUnit locale_get_measurement_unit(void);
|
||||||
|
void locale_set_measurement_unit(LocaleMeasurementUnit format);
|
||||||
|
|
||||||
|
float locale_fahrenheit_to_celsius(float temp_f);
|
||||||
|
float locale_celsius_to_fahrenheit(float temp_c);
|
||||||
|
|
||||||
|
LocaleTimeFormat locale_get_time_format(void);
|
||||||
|
void locale_set_time_format(LocaleTimeFormat format);
|
||||||
|
|
||||||
|
void locale_format_time(
|
||||||
|
FuriString* out_str,
|
||||||
|
FuriHalRtcDateTime* datetime,
|
||||||
|
LocaleTimeFormat format,
|
||||||
|
bool show_seconds);
|
||||||
|
|
||||||
|
LocaleDateFormat locale_get_date_format(void);
|
||||||
|
void locale_set_date_format(LocaleDateFormat format);
|
||||||
|
|
||||||
|
void locale_format_date(
|
||||||
|
FuriString* out_str,
|
||||||
|
FuriHalRtcDateTime* datetime,
|
||||||
|
LocaleDateFormat format,
|
||||||
|
char* separator);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -3,7 +3,7 @@ App(
|
|||||||
name="System",
|
name="System",
|
||||||
apptype=FlipperAppType.SETTINGS,
|
apptype=FlipperAppType.SETTINGS,
|
||||||
entry_point="system_settings_app",
|
entry_point="system_settings_app",
|
||||||
requires=["gui"],
|
requires=["gui", "locale"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
order=70,
|
order=70,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "system_settings.h"
|
#include "system_settings.h"
|
||||||
#include <loader/loader.h>
|
#include <loader/loader.h>
|
||||||
#include <lib/toolbox/value_index.h>
|
#include <lib/toolbox/value_index.h>
|
||||||
|
#include <locale/locale.h>
|
||||||
|
|
||||||
const char* const log_level_text[] = {
|
const char* const log_level_text[] = {
|
||||||
"Default",
|
"Default",
|
||||||
@@ -70,6 +71,59 @@ static void heap_trace_mode_changed(VariableItem* item) {
|
|||||||
furi_hal_rtc_set_heap_track_mode(heap_trace_mode_value[index]);
|
furi_hal_rtc_set_heap_track_mode(heap_trace_mode_value[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* const mesurement_units_text[] = {
|
||||||
|
"Metric",
|
||||||
|
"Imperial",
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t mesurement_units_value[] = {
|
||||||
|
LocaleMeasurementUnitMetric,
|
||||||
|
LocaleMeasurementUnitImperial,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mesurement_units_changed(VariableItem* item) {
|
||||||
|
// SystemSettings* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, mesurement_units_text[index]);
|
||||||
|
locale_set_measurement_unit(mesurement_units_value[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* const time_format_text[] = {
|
||||||
|
"24h",
|
||||||
|
"12h",
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t time_format_value[] = {
|
||||||
|
LocaleTimeFormat24h,
|
||||||
|
LocaleTimeFormat12h,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void time_format_changed(VariableItem* item) {
|
||||||
|
// SystemSettings* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, time_format_text[index]);
|
||||||
|
locale_set_time_format(time_format_value[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* const date_format_text[] = {
|
||||||
|
"D/M/Y",
|
||||||
|
"M/D/Y",
|
||||||
|
"Y/M/D",
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t date_format_value[] = {
|
||||||
|
LocaleDateFormatDMY,
|
||||||
|
LocaleDateFormatMDY,
|
||||||
|
LocaleDateFormatYMD,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void date_format_changed(VariableItem* item) {
|
||||||
|
// SystemSettings* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, date_format_text[index]);
|
||||||
|
locale_set_date_format(date_format_value[index]);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t system_settings_exit(void* context) {
|
static uint32_t system_settings_exit(void* context) {
|
||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
return VIEW_NONE;
|
return VIEW_NONE;
|
||||||
@@ -91,6 +145,31 @@ SystemSettings* system_settings_alloc() {
|
|||||||
uint8_t value_index;
|
uint8_t value_index;
|
||||||
app->var_item_list = variable_item_list_alloc();
|
app->var_item_list = variable_item_list_alloc();
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
app->var_item_list,
|
||||||
|
"Units",
|
||||||
|
COUNT_OF(mesurement_units_text),
|
||||||
|
mesurement_units_changed,
|
||||||
|
app);
|
||||||
|
value_index = value_index_uint32(
|
||||||
|
locale_get_measurement_unit(), mesurement_units_value, COUNT_OF(mesurement_units_value));
|
||||||
|
variable_item_set_current_value_index(item, value_index);
|
||||||
|
variable_item_set_current_value_text(item, mesurement_units_text[value_index]);
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
app->var_item_list, "Time Format", COUNT_OF(time_format_text), time_format_changed, app);
|
||||||
|
value_index = value_index_uint32(
|
||||||
|
locale_get_time_format(), time_format_value, COUNT_OF(time_format_value));
|
||||||
|
variable_item_set_current_value_index(item, value_index);
|
||||||
|
variable_item_set_current_value_text(item, time_format_text[value_index]);
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
app->var_item_list, "Date Format", COUNT_OF(date_format_text), date_format_changed, app);
|
||||||
|
value_index = value_index_uint32(
|
||||||
|
locale_get_date_format(), date_format_value, COUNT_OF(date_format_value));
|
||||||
|
variable_item_set_current_value_index(item, value_index);
|
||||||
|
variable_item_set_current_value_text(item, date_format_text[value_index]);
|
||||||
|
|
||||||
item = variable_item_list_add(
|
item = variable_item_list_add(
|
||||||
app->var_item_list, "Log Level", COUNT_OF(log_level_text), log_level_changed, app);
|
app->var_item_list, "Log Level", COUNT_OF(log_level_text), log_level_changed, app);
|
||||||
value_index = value_index_uint32(
|
value_index = value_index_uint32(
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ DEBUG = 0
|
|||||||
|
|
||||||
# Suffix to add to files when building distribution
|
# Suffix to add to files when building distribution
|
||||||
# If OS environment has DIST_SUFFIX set, it will be used instead
|
# If OS environment has DIST_SUFFIX set, it will be used instead
|
||||||
DIST_SUFFIX = "CC_CL-0011"
|
DIST_SUFFIX = "CC_CL-0012"
|
||||||
|
|
||||||
# Coprocessor firmware
|
# Coprocessor firmware
|
||||||
COPRO_OB_DATA = "scripts/ob.data"
|
COPRO_OB_DATA = "scripts/ob.data"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,11.0,,
|
Version,+,12.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@@ -30,6 +30,7 @@ Header,+,applications/services/gui/view_dispatcher.h,,
|
|||||||
Header,+,applications/services/gui/view_stack.h,,
|
Header,+,applications/services/gui/view_stack.h,,
|
||||||
Header,+,applications/services/input/input.h,,
|
Header,+,applications/services/input/input.h,,
|
||||||
Header,+,applications/services/loader/loader.h,,
|
Header,+,applications/services/loader/loader.h,,
|
||||||
|
Header,+,applications/services/locale/locale.h,,
|
||||||
Header,+,applications/services/notification/notification.h,,
|
Header,+,applications/services/notification/notification.h,,
|
||||||
Header,+,applications/services/notification/notification_messages.h,,
|
Header,+,applications/services/notification/notification_messages.h,,
|
||||||
Header,+,applications/services/power/power_service/power.h,,
|
Header,+,applications/services/power/power_service/power.h,,
|
||||||
@@ -784,6 +785,7 @@ Function,+,elements_scrollbar_pos,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint
|
|||||||
Function,+,elements_slightly_rounded_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
|
Function,+,elements_slightly_rounded_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
|
||||||
Function,+,elements_slightly_rounded_frame,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
|
Function,+,elements_slightly_rounded_frame,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
|
||||||
Function,+,elements_string_fit_width,void,"Canvas*, FuriString*, uint8_t"
|
Function,+,elements_string_fit_width,void,"Canvas*, FuriString*, uint8_t"
|
||||||
|
Function,+,elements_string_fit_width_trunc,void,"Canvas*, FuriString*, uint8_t"
|
||||||
Function,+,elements_text_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool"
|
Function,+,elements_text_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool"
|
||||||
Function,+,empty_screen_alloc,EmptyScreen*,
|
Function,+,empty_screen_alloc,EmptyScreen*,
|
||||||
Function,+,empty_screen_free,void,EmptyScreen*
|
Function,+,empty_screen_free,void,EmptyScreen*
|
||||||
@@ -1771,6 +1773,16 @@ Function,+,loader_update_menu,void,
|
|||||||
Function,+,loading_alloc,Loading*,
|
Function,+,loading_alloc,Loading*,
|
||||||
Function,+,loading_free,void,Loading*
|
Function,+,loading_free,void,Loading*
|
||||||
Function,+,loading_get_view,View*,Loading*
|
Function,+,loading_get_view,View*,Loading*
|
||||||
|
Function,+,locale_celsius_to_fahrenheit,float,float
|
||||||
|
Function,+,locale_fahrenheit_to_celsius,float,float
|
||||||
|
Function,+,locale_format_date,void,"FuriString*, FuriHalRtcDateTime*, LocaleDateFormat, char*"
|
||||||
|
Function,+,locale_format_time,void,"FuriString*, FuriHalRtcDateTime*, LocaleTimeFormat, _Bool"
|
||||||
|
Function,+,locale_get_date_format,LocaleDateFormat,
|
||||||
|
Function,+,locale_get_measurement_unit,LocaleMeasurementUnit,
|
||||||
|
Function,+,locale_get_time_format,LocaleTimeFormat,
|
||||||
|
Function,+,locale_set_date_format,void,LocaleDateFormat
|
||||||
|
Function,+,locale_set_measurement_unit,void,LocaleMeasurementUnit
|
||||||
|
Function,+,locale_set_time_format,void,LocaleTimeFormat
|
||||||
Function,-,localtime,tm*,const time_t*
|
Function,-,localtime,tm*,const time_t*
|
||||||
Function,-,localtime_r,tm*,"const time_t*, tm*"
|
Function,-,localtime_r,tm*,"const time_t*, tm*"
|
||||||
Function,-,log,double,double
|
Function,-,log,double,double
|
||||||
|
|||||||
|
@@ -31,10 +31,13 @@ typedef struct {
|
|||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t boot_mode : 4;
|
uint8_t boot_mode : 4;
|
||||||
uint8_t heap_track_mode : 2;
|
uint8_t heap_track_mode : 2;
|
||||||
uint16_t reserved : 10;
|
uint8_t locale_units : 1;
|
||||||
} DeveloperReg;
|
uint8_t locale_timeformat : 1;
|
||||||
|
uint8_t locale_dateformat : 2;
|
||||||
|
uint8_t reserved : 6;
|
||||||
|
} SystemReg;
|
||||||
|
|
||||||
_Static_assert(sizeof(DeveloperReg) == 4, "DeveloperReg size mismatch");
|
_Static_assert(sizeof(SystemReg) == 4, "SystemReg size mismatch");
|
||||||
|
|
||||||
#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60
|
#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60
|
||||||
#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60)
|
#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60)
|
||||||
@@ -172,7 +175,7 @@ void furi_hal_rtc_set_register(FuriHalRtcRegister reg, uint32_t value) {
|
|||||||
|
|
||||||
void furi_hal_rtc_set_log_level(uint8_t level) {
|
void furi_hal_rtc_set_log_level(uint8_t level) {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
data->log_level = level;
|
data->log_level = level;
|
||||||
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
furi_log_set_level(level);
|
furi_log_set_level(level);
|
||||||
@@ -180,13 +183,13 @@ void furi_hal_rtc_set_log_level(uint8_t level) {
|
|||||||
|
|
||||||
uint8_t furi_hal_rtc_get_log_level() {
|
uint8_t furi_hal_rtc_get_log_level() {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
return data->log_level;
|
return data->log_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) {
|
void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
data->flags |= flag;
|
data->flags |= flag;
|
||||||
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
|
|
||||||
@@ -197,7 +200,7 @@ void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) {
|
|||||||
|
|
||||||
void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) {
|
void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
data->flags &= ~flag;
|
data->flags &= ~flag;
|
||||||
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
|
|
||||||
@@ -208,36 +211,74 @@ void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) {
|
|||||||
|
|
||||||
bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) {
|
bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
return data->flags & flag;
|
return data->flags & flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode) {
|
void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode) {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
data->boot_mode = mode;
|
data->boot_mode = mode;
|
||||||
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
FuriHalRtcBootMode furi_hal_rtc_get_boot_mode() {
|
FuriHalRtcBootMode furi_hal_rtc_get_boot_mode() {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
return (FuriHalRtcBootMode)data->boot_mode;
|
return (FuriHalRtcBootMode)data->boot_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode) {
|
void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode) {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
data->heap_track_mode = mode;
|
data->heap_track_mode = mode;
|
||||||
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode() {
|
FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode() {
|
||||||
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
DeveloperReg* data = (DeveloperReg*)&data_reg;
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
return (FuriHalRtcHeapTrackMode)data->heap_track_mode;
|
return (FuriHalRtcHeapTrackMode)data->heap_track_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void furi_hal_rtc_set_locale_units(uint8_t mode) {
|
||||||
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
|
data->locale_units = mode;
|
||||||
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t furi_hal_rtc_get_locale_units() {
|
||||||
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
|
return (uint8_t)data->locale_units;
|
||||||
|
}
|
||||||
|
|
||||||
|
void furi_hal_rtc_set_locale_timeformat(uint8_t mode) {
|
||||||
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
|
data->locale_timeformat = mode;
|
||||||
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t furi_hal_rtc_get_locale_timeformat() {
|
||||||
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
|
return (uint8_t)data->locale_timeformat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void furi_hal_rtc_set_locale_dateformat(uint8_t mode) {
|
||||||
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
|
data->locale_dateformat = mode;
|
||||||
|
furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t furi_hal_rtc_get_locale_dateformat() {
|
||||||
|
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem);
|
||||||
|
SystemReg* data = (SystemReg*)&data_reg;
|
||||||
|
return (uint8_t)data->locale_dateformat;
|
||||||
|
}
|
||||||
void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) {
|
void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) {
|
||||||
furi_assert(datetime);
|
furi_assert(datetime);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user