From 5b8efa87d7380ed8bc87610eed683bccfe079414 Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Sun, 6 Oct 2024 11:56:24 -0400 Subject: [PATCH] watch_display_float_with_best_effort: support negative numbers --- watch-faces/demo/float_demo_face.c | 20 +++++++++----- .../shared/watch/watch_common_display.c | 26 ++++++++++++++++--- watch-library/shared/watch/watch_slcd.h | 13 +++++----- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/watch-faces/demo/float_demo_face.c b/watch-faces/demo/float_demo_face.c index fa650d28..440fa09d 100644 --- a/watch-faces/demo/float_demo_face.c +++ b/watch-faces/demo/float_demo_face.c @@ -33,20 +33,28 @@ void float_demo_face_setup(uint8_t watch_face_index, void ** context_ptr) { } void float_demo_face_activate(void *context) { - float *c = (float *)context; - *c = 0; + float *value = (float *)context; + *value = -110; watch_display_text_with_fallback(WATCH_POSITION_TOP, "FLOAT", "FL"); - movement_request_tick_frequency(32); + movement_request_tick_frequency(16); } bool float_demo_face_loop(movement_event_t event, void *context) { - float *c = (float *)context; + float *value = (float *)context; switch (event.event_type) { case EVENT_TICK: - *c = (*c) + 0.11; + *value = (*value) + 0.31; // fall through case EVENT_ACTIVATE: - watch_display_float_with_best_effort(*c, "#F"); + watch_display_float_with_best_effort(*value, "#F"); + break; + case EVENT_ALARM_BUTTON_UP: + *value = -100; + movement_request_tick_frequency(16); + break; + case EVENT_ALARM_LONG_PRESS: + *value = -10.85; + movement_request_tick_frequency(1); break; default: movement_default_loop_handler(event); diff --git a/watch-library/shared/watch/watch_common_display.c b/watch-library/shared/watch/watch_common_display.c index 7e443293..312705cd 100644 --- a/watch-library/shared/watch/watch_common_display.c +++ b/watch-library/shared/watch/watch_common_display.c @@ -26,6 +26,8 @@ #include "watch_common_display.h" #include #include +#include +#include #ifdef USE_CUSTOM_LCD static const uint32_t IndicatorSegments[] = { @@ -275,7 +277,7 @@ void watch_display_float_with_best_effort(float value, const char *units) { char buf_fallback[8]; const char *blank_units = " "; - if (value < 0.0) { + if (value < -99.9) { watch_clear_decimal_if_available(); watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, "Undflo", " Unflo"); return; @@ -285,8 +287,20 @@ void watch_display_float_with_best_effort(float value, const char *units) { return; } - uint16_t value_times_100 = (uint16_t)(value * 100.0); - if (value_times_100 > 9999) { + uint16_t value_times_100 = abs((int)round(value * 100.0)); + bool set_decimal = true; + + if (value < 0 && value_times_100 != 0) { + if (value_times_100 > 999) { + // decimal point isn't in the right place for these numbers; use same format as classic. + set_decimal = false; + snprintf(buf, sizeof(buf), "-%4.1f%s", -value, units ? units : blank_units); + snprintf(buf_fallback, sizeof(buf_fallback), "%s", buf); + } else { + snprintf(buf, sizeof(buf), "-%03d%s", value_times_100 % 1000u, units ? units : blank_units); + snprintf(buf_fallback, sizeof(buf_fallback), "-%3.1f%s", -value, units ? units : blank_units); + } + } else if (value_times_100 > 9999) { snprintf(buf, sizeof(buf), "%5u%s", value_times_100, units ? units : blank_units); snprintf(buf_fallback, sizeof(buf_fallback), "%4.1f%s", value, units ? units : blank_units); } else if (value_times_100 > 999) { @@ -298,7 +312,11 @@ void watch_display_float_with_best_effort(float value, const char *units) { } watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, buf, buf_fallback); - watch_set_decimal_if_available(); + if (set_decimal) { + watch_set_decimal_if_available(); + } else { + watch_clear_decimal_if_available(); + } } void watch_set_colon(void) { diff --git a/watch-library/shared/watch/watch_slcd.h b/watch-library/shared/watch/watch_slcd.h index b369b3b5..1c69d2fb 100644 --- a/watch-library/shared/watch/watch_slcd.h +++ b/watch-library/shared/watch/watch_slcd.h @@ -163,12 +163,13 @@ void watch_display_text_with_fallback(watch_position_t location, const char *str /** * @brief Displays a floating point number as best we can on whatever LCD is available. * @details The custom LCD can energize a decimal point in the same position as the colon. With the leading 1, - * we can display numbers from 0.00 to 199.99 with two digits of precision. The original F-91W LCD has - * no decimal point, so we use a hyphen to indicate the decimal point. For floats from 0.00 to 9.99, - * we can display the number with two digits after the "decimal point" (hyphen). For floats from 10.0 - * to 99.9, you'll only get one digit after the hyphen. For floats from 100 to 199.9, we'll still give - * you one digit after the hyphen, but you'll lose the second character of your units. - * @param value A floating point number from 0.00 to 199.99 to display on the main clock digits. + * we can display numbers from -99.99 to 199.99 with one or two digits of precision, depending on the + * number and the LCD in use (classic LCD, usually 1 digit; custom LCD, usually 2). The original F-91W + * LCD has no decimal point, so we use a hyphen or underscore instead. For numbers <9.99, the decimal + * point will appear as an underscore on the custom LCD as well, since the position doesn't line up. + * Also note that sometimes, to offer at least one digit of precision, the second character of your + * units may be truncated (i.e. -12.4#F will become -12.4#). + * @param value A floating point number from -99.99 to 199.99 to display on the main line of the display. * @param units A 1-2 character string to display in the seconds position. Second character may be truncated. */ void watch_display_float_with_best_effort(float value, const char *units);