]> git.earman.xyz Git - sensor-watch.git/commitdiff
improve API for text display
authorjoeycastillo <joeycastillo@utexas.edu>
Thu, 19 Sep 2024 12:42:07 +0000 (08:42 -0400)
committerjoeycastillo <joeycastillo@utexas.edu>
Thu, 19 Sep 2024 12:42:07 +0000 (08:42 -0400)
watch-faces/clock/simple_clock_face.c
watch-faces/settings/set_time_face.c
watch-library/shared/watch/watch_common_display.c
watch-library/shared/watch/watch_slcd.h

index 0f12b0ec093e30dce141d7a64d6e6dbdce5541a4..54bfdb3f25950a59edce6ea64929337ce1af36b6 100644 (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);
                 }
             }
 
index dd9b96df8044f821f82f8f0e244caa4634e59368..549ad8b765b797d4acd5e71fab3a2f00198d65f9 100644 (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;
         }
     }
index bab82b0e2ccee2284956f2cc007eeaa1d41beb0f..66c5c75b2c07e1f7ff1d34cba81c368adc323dcb 100644 (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);
-    }
-#else
-    (void)string;
-    watch_display_top_left(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++;
+    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_main_line(fallback);
+    watch_display_text(location, 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);
index 320e52b5e233ae3d0007c1a4e1acda380bb0cace..cfd0cac5d290c573903b9915a07dca4c1e142ed9 100644 (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.
- */
-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.
+ *       Needless to say, some fine-tuning may be necessary to get the best results on both displays.
  */
-void watch_display_seconds(char *string);
+void watch_display_text_with_fallback(WatchDisplayLocation location, char *string, char *fallback);
 
 /** @brief Turns the colon segment on.
   */