improve API for text display

This commit is contained in:
joeycastillo 2024-09-19 08:42:07 -04:00
parent 8bbcacd747
commit 9274f532d2
4 changed files with 160 additions and 182 deletions

View File

@ -120,15 +120,15 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting
if (date_time.unit.hour == 0) date_time.unit.hour = 12;
}
#endif
watch_display_top_left((char *) watch_utility_get_weekday(date_time));
watch_display_text(WATCH_POSITION_TOP_LEFT, (char *) watch_utility_get_weekday(date_time));
sprintf(buf, "%2d%2d%02d%02d", date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
watch_display_top_right(buf);
watch_display_hours(buf + 2);
watch_display_minutes(buf + 4);
watch_display_text(WATCH_POSITION_TOP_RIGHT, buf);
watch_display_text(WATCH_POSITION_HOURS, buf + 2);
watch_display_text(WATCH_POSITION_MINUTES, buf + 4);
if (event.event_type == EVENT_LOW_ENERGY_UPDATE) {
if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
} else {
watch_display_seconds(buf + 6);
watch_display_text(WATCH_POSITION_SECONDS, buf + 6);
}
}

View File

@ -127,8 +127,8 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v
}
char buf[11];
watch_display_top_left((char *) set_time_face_titles[current_page]);
watch_display_top_right(" ");
watch_display_text(WATCH_POSITION_TOP_LEFT, (char *) set_time_face_titles[current_page]);
watch_display_text(WATCH_POSITION_TOP_RIGHT, " ");
if (current_page < 3) {
watch_set_colon();
if (settings->bit.clock_mode_24h) {
@ -150,27 +150,27 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v
memset(buf, ' ', sizeof(buf));
} else {
watch_set_colon();
if (movement_timezone_offsets[settings->bit.time_zone] < 0) watch_display_top_right(" -");
if (movement_timezone_offsets[settings->bit.time_zone] < 0) watch_display_text(WATCH_POSITION_TOP_RIGHT, " -");
sprintf(buf, "%2d%02d ", (int8_t) abs(movement_timezone_offsets[settings->bit.time_zone] / 60), (int8_t) (movement_timezone_offsets[settings->bit.time_zone] % 60) * (movement_timezone_offsets[settings->bit.time_zone] < 0 ? -1 : 1));
}
}
watch_display_main_line(buf);
watch_display_text(WATCH_POSITION_BOTTOM, buf);
// blink up the parameter we're setting
if (event.subsecond % 2 && !_quick_ticks_running) {
switch (current_page) {
case 0:
case 3:
watch_display_hours(" ");
watch_display_text(WATCH_POSITION_HOURS, " ");
break;
case 1:
case 4:
watch_display_minutes(" ");
watch_display_text(WATCH_POSITION_MINUTES, " ");
break;
case 2:
case 5:
watch_display_seconds(" ");
watch_display_text(WATCH_POSITION_SECONDS, " ");
break;
}
}

View File

@ -150,103 +150,114 @@ void watch_display_string(char *string, uint8_t position) {
}
}
void watch_display_top_left(char *string) {
watch_display_character(string[0], 0);
if (string[1]) {
watch_display_character(string[1], 1);
void watch_display_text(WatchDisplayLocation location, char *string) {
switch (location) {
case WATCH_POSITION_TOP_LEFT:
watch_display_character(string[0], 0);
if (string[1]) {
watch_display_character(string[1], 1);
}
break;
case WATCH_POSITION_TOP_RIGHT:
watch_display_character(string[0], 2);
if (string[1]) {
watch_display_character(string[1], 3);
}
break;
case WATCH_POSITION_BOTTOM:
{
#ifdef USE_CUSTOM_LCD
watch_clear_pixel(0, 22);
#endif
int i = 0;
while (string[i] != 0) {
watch_display_character(string[i], 4 + i);
i++;
}
}
break;
case WATCH_POSITION_HOURS:
watch_display_character(string[0], 4);
if (string[1]) {
watch_display_character(string[1], 5);
}
break;
case WATCH_POSITION_MINUTES:
watch_display_character(string[0], 6);
if (string[1]) {
watch_display_character(string[1], 7);
}
break;
case WATCH_POSITION_SECONDS:
watch_display_character(string[0], 8);
if (string[1]) {
watch_display_character(string[1], 9);
}
break;
case WATCH_POSITION_FULL:
default:
// This is deprecated, but we use it for the legacy behavior.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
watch_display_string(string, 0);
#pragma GCC diagnostic pop
}
}
void watch_display_top_left_with_fallback(char *string, char *fallback) {
void watch_display_text_with_fallback(WatchDisplayLocation location, char *string, char *fallback) {
#ifdef USE_CUSTOM_LCD
(void)fallback;
watch_display_character(string[0], 0);
if (string[1]) {
watch_display_character(string[1], 1);
} else {
return;
}
if (string[2]) {
// position 3 is at index 10 in the display mapping
watch_display_character(string[2], 10);
switch (location) {
case WATCH_POSITION_TOP_LEFT:
watch_display_character(string[0], 0);
if (string[1]) {
watch_display_character(string[1], 1);
} else {
return;
}
if (string[2]) {
// position 3 is at index 10 in the display mapping
watch_display_character(string[2], 10);
}
break;
case WATCH_POSITION_BOTTOM:
{
watch_clear_pixel(0, 22);
int i = 0;
int offset = 0;
size_t len = strlen(string);
if (len == 7 && string[0] == '1') {
watch_set_pixel(0, 22);
offset = 1;
i++;
}
while (string[i] != 0) {
watch_display_character(string[i], 4 + i - offset);
i++;
}
}
break;
case WATCH_POSITION_TOP_RIGHT:
case WATCH_POSITION_HOURS:
case WATCH_POSITION_MINUTES:
case WATCH_POSITION_SECONDS:
watch_display_text(location, string);
break;
case WATCH_POSITION_FULL:
default:
// This is deprecated, but we use it for the legacy behavior.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
watch_display_string(string, 0);
#pragma GCC diagnostic pop
}
#else
(void)string;
watch_display_top_left(fallback);
watch_display_text(location, fallback);
#endif
}
void watch_display_top_right(char *string) {
watch_display_character(string[0], 2);
if (string[1]) {
watch_display_character(string[1], 3);
}
}
void watch_display_top_right_with_fallback(char *string, char *fallback) {
#ifdef USE_CUSTOM_LCD
(void)fallback;
watch_display_top_right(string);
#else
(void)string;
watch_display_top_right(fallback);
#endif
}
void watch_display_main_line(char *string) {
#ifdef USE_CUSTOM_LCD
watch_clear_pixel(0, 22);
#endif
int i = 0;
while (string[i] != 0) {
watch_display_character(string[i], 4 + i);
i++;
}
}
void watch_display_main_line_with_fallback(char *string, char *fallback) {
#ifdef USE_CUSTOM_LCD
(void)fallback;
watch_clear_pixel(0, 22);
int i = 0;
int offset = 0;
size_t len = strlen(string);
if (len == 7 && string[0] == '1') {
watch_set_pixel(0, 22);
offset = 1;
i++;
}
while (string[i] != 0) {
watch_display_character(string[i], 4 + i - offset);
i++;
}
#else
(void)string;
watch_display_main_line(fallback);
#endif
}
void watch_display_hours(char *string) {
watch_display_character(string[0], 4);
if (string[1]) {
watch_display_character(string[1], 5);
}
}
void watch_display_minutes(char *string) {
watch_display_character(string[0], 6);
if (string[1]) {
watch_display_character(string[1], 7);
}
}
void watch_display_seconds(char *string) {
watch_display_character(string[0], 8);
if (string[1]) {
watch_display_character(string[1], 9);
}
}
void watch_set_colon(void) {
#ifdef USE_CUSTOM_LCD
watch_set_pixel(0, 0);

View File

@ -59,6 +59,17 @@ typedef enum WatchIndicatorSegment {
WATCH_INDICATOR_SLEEP, ///< The sleep indicator. No fallback here; use the tick animation to indicate sleep.
} WatchIndicatorSegment;
/// An enum listing the locations on the display where text can be placed.
typedef enum WatchDisplayLocation {
WATCH_POSITION_FULL = 0, ///< Display 10 characters to the full screen, in the standard F-91W layout.
WATCH_POSITION_TOP_LEFT, ///< Display 2 or 3 characters in the top left of the screen.
WATCH_POSITION_TOP_RIGHT, ///< Display 2 digits in the top right of the screen.
WATCH_POSITION_BOTTOM, ///< Display 6 characters at the bottom of the screen, the main line.
WATCH_POSITION_HOURS, ///< Display 2 characters in the hours portion of the main line.
WATCH_POSITION_MINUTES, ///< Display 2 characters in the minutes portion of the main line.
WATCH_POSITION_SECONDS, ///< Display 2 characters in the seconds portion of the main line.
} WatchDisplayLocation;
/** @brief Enables the Segment LCD display.
* Call this before attempting to set pixels or display strings.
*/
@ -93,101 +104,57 @@ void watch_clear_display(void);
* @note This method does not clear the display; if for example you display a two-character string at
position 0, positions 2-9 will retain whatever state they were previously displaying.
*/
void watch_display_string(char *string, uint8_t position) __attribute__ ((deprecated("Use watch_display_top_left, watch_display_top_right and watch_display_main_line instead.")));
void watch_display_string(char *string, uint8_t position) __attribute__ ((deprecated("Use watch_display_text and watch_display_text_with_fallback instead.")));
/**
* @brief Displays a string at in the digits at the top left, which typically show the day of the week.
* @brief Displays a string at the provided location.
* @param location @see WatchDisplayLocation, the location where you wish to display the string.
* @param string A null-terminated string with two characters to display.
*/
void watch_display_top_left(char *string);
void watch_display_text(WatchDisplayLocation location, char *string);
/**
* @brief Displays a string at in the digits at the top left, which typically show the day of the week.
* @details This function is designed to make use of the new custom LCD, which has three digits at the
* top left. If you are using the original F-91W LCD, this function will fall back to displaying
* the fallback string. So for example if you were displaying a world clock for Anchorage, you
* could pass "ANC" as the string, and "AN" as the fallback.
* @param string A null-terminated string with 1-3 characters to display on the custom LCD.
* @param fallback A null-terminated string with 1-2 characters to display on the original F-91W LCD.
* @brief Displays a string at the provided location on the new LCD, with a fallback for the original.
* @details This function is designed to make use of the new custom LCD, which has more possibilities
* than the original. If you are using the original F-91W LCD, this function will fall back to
* displaying the fallback string. So for example if you were displaying a world clock for
* Anchorage, you could title the screen in the top left position: pass "ANC" as the string,
* and "AN" as the fallback.
* @param string A null-terminated string to display on the custom LCD.
* @param fallback A null-terminated string to display on the original F-91W LCD.
* @note Both the custom LCD and the original F-91W LCD have some limitations on what characters can be
* displayed. For example, the custom LCD can display "NYC" but the original F-91W LCD can't
* display "NY" due to the shared segments in position 1. On the other hand the original F-91W
* can display "FR" for Friday thanks to its extra segment in position 1, but the custom LCD can
* only display lowercase R, "Fri", due to the more simplistic 8-segment design of all the sigits.
* Some fine-tuning may be necessary to get the best results on both displays.
*/
void watch_display_top_left_with_fallback(char *string, char *fallback);
/**
* @brief Displays a string in the digits at the top right, which typically show the day of the month.
* @param string A null-terminated string with two characters to display.
*/
void watch_display_top_right(char *string);
/**
* @brief Displays a string in the digits at the top right, which typically show the day of the month.
* @param string A null-terminated string with two characters to display on the custom LCD.
* @param fallback A null-terminated string with two characters to display on the original F-91W LCD.
* @note On the original F-91W LCD, position 2 can only display the numbers 1, 2 and 3 (or a
* lowercase 'a') due to its aggressive segment sharing in this position. You may need to come
* up with more complex logic to create a useful fallback if displaying other characters here.
* Position 3, the second digit, is a standard 7-segment digit.
*/
void watch_display_top_right_with_fallback(char *string, char *fallback);
/**
* @brief Displays a string in the main line of the display, which typically shows the time.
* @param string A null-terminated string with six characters to display. Omit the colon; if you want
* the colon to appear, use watch_set_colon() to turn it on.
*/
void watch_display_main_line(char *string);
/**
* @brief Displays a string in the main line of the display, which typically shows the time.
* @param string A null-terminated string with 7 characters to display. The first character must be
* either a 1 or a space; on the custom LCD, this will indicate whether to turn on the leading
* '1' segment. Omit any colons or decimal points.
* @param fallback A null-terminated string with 6 characters to display if the custom LCD is not
* available. Once again, omit the colon.
* @note This function is a bit more complicated, but the gist is, the custom LCD can display
* "1888888", while the original F-91W LCD can only display "888888". In addition, on the original
* Casio LCD, the first digit of the hours and seconds display have their top and bottom segments
* linked, which causes some limitations. The intent is for you to use the function like this,
* for example, displaying a longutide and latitude:
* displayed:
* * At the top left, the custom LCD can display "NYC" but the original F-91W LCD can't display "NY"
* due to the shared segments in position 1 (Try "MA" for Manhattan or "BR" for Brooklyn / Bronx.)
* On the other hand, the original F-91W can display "FR" for Friday thanks to its extra segment in
* position 1, but the custom LCD can only display lowercase R, "Fri", due to the more simplistic
* 8-segment design of all the digits.
* * On the top right, the original F-91W LCD can only display numbers from 0 to 39, while the custom
* LCD can display any two 7-segment characters. Thus something like a 60 second countdown may have
* to display some fallback when more than 40 seconds remain, then switch to counting down from 39.
* * In the main line, the original F-91W LCD can only display "888888", while the custom LCD can
* display "188.8888". This will require some creativity; for example, when displaying a longutide
* and latitude:
*
* watch_display_main_line_with_fallback("14990#W", "-14990") // "149.90°W" or "-149.90"
* watch_display_main_line_with_fallback(" 6122#N", "+ 6122") // "61.22°N" or "+61.22"
* watch_display_main_line_with_fallback("14990#W", "-14990") // "149.90°W" or "-149.90"
* watch_display_main_line_with_fallback(" 6122#N", "+ 6122") // "61.22°N" or "+61.22"
*
* In the first example, the leading 1 allows us to dusplay "146.90°W" on the custom LCD, with the
* numeric portion in the clock digits, and the "°W" hint in the small seconds digits. Meanwhile on
* the classic LCD, the fallback string "-14990" will display -149 in the large clock digits, and
* 90 in the small seconds digits, indicating that this is a decimal portion.
* In the second example, the leading space allows us to display "61.22°N" on the custom LCD, with
* the "°N" in the seconds place, while the fallback string "+ 6122" will display +61 on the large
* clock digits, and 22 in the small seconds digits, indicating that this is a decimal portion.
* In the first example, the leading 1 allows us to dusplay "146.90°W" on the custom LCD, with the
* numeric portion in the clock digits, and the "°W" hint in the small seconds digits. Meanwhile on
* the classic LCD, the fallback string "-14990" will display -149 in the large clock digits, and
* 90 in the small seconds digits, indicating that this is a decimal portion.
* In the second example, the leading space allows us to display "61.22°N" on the custom LCD, with
* the "°N" in the seconds place, while the fallback string "+ 6122" will display +61 on the large
* clock digits, and 22 in the small seconds digits, indicating that this is a decimal portion.
* In addition, on the original Casio LCD, the first digit of the hours and seconds display have
* their top and bottom segments linked, which causes some limitations (like the short "lowercase"
* '7', and the inability to use 'b', 'd', 'f', 'k', 'p', 'q', 't', 'x' or 'y' in those spots. You
* may need to shift your fallback string to the right or left to avoid putting these characters
* in the first digit of the hours or minutes.
*
* Note also that the custom LCD has a vertical descender in the two seconds digits, which can be
* used to displaty uppercase letters like D, I, T, M and W.
* Needless to say, some fine-tuning may be necessary to get the best results on both displays.
*/
void watch_display_main_line_with_fallback(char *string, char *fallback);
/**
* @brief Displays a string in the hours portion of the main line.
* @param string A null-terminated string with two characters to display.
*/
void watch_display_hours(char *string);
/**
* @brief Displays a string in the minutes portion of the main line.
* @param string A null-terminated string with two characters to display.
*/
void watch_display_minutes(char *string);
/**
* @brief Displays a string in the seconds portion of the main line.
* @param string A null-terminated string with two characters to display.
*/
void watch_display_seconds(char *string);
void watch_display_text_with_fallback(WatchDisplayLocation location, char *string, char *fallback);
/** @brief Turns the colon segment on.
*/