Update Kitchen Conversions Face for Second Movement (#24)

* Basic second movement support

* Switch alarm and light button functionality
This commit is contained in:
PrimmR 2025-07-06 16:47:12 +01:00 committed by GitHub
parent 5864af1c56
commit 2e5e094bb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 53 deletions

View File

@ -51,6 +51,7 @@
#include "nanosec_face.h" #include "nanosec_face.h"
#include "mars_time_face.h" #include "mars_time_face.h"
#include "peek_memory_face.h" #include "peek_memory_face.h"
#include "kitchen_conversions_face.h"
#include "periodic_table_face.h" #include "periodic_table_face.h"
#include "squash_face.h" #include "squash_face.h"
#include "totp_face.h" #include "totp_face.h"

View File

@ -28,5 +28,6 @@ SRCS += \
./watch-faces/settings/nanosec_face.c \ ./watch-faces/settings/nanosec_face.c \
./watch-faces/io/chirpy_demo_face.c \ ./watch-faces/io/chirpy_demo_face.c \
./watch-faces/io/irda_upload_face.c \ ./watch-faces/io/irda_upload_face.c \
./watch-faces/complication/kitchen_conversions_face.c \
./watch-faces/complication/periodic_table_face.c \ ./watch-faces/complication/periodic_table_face.c \
# New watch faces go above this line. # New watch faces go above this line.

View File

@ -26,6 +26,8 @@
#include <string.h> #include <string.h>
#include "kitchen_conversions_face.h" #include "kitchen_conversions_face.h"
#include "watch_common_display.h"
typedef struct typedef struct
{ {
char name[6]; // Name to display on selection char name[6]; // Name to display on selection
@ -41,8 +43,9 @@ typedef struct
#define TEMP 1 #define TEMP 1
#define VOL 2 #define VOL 2
// Names of measurements // Names of measurements (classic & custom LCD)
static char measures[MEASURES_COUNT][6] = {"WeIght", " Temp", " VOL"}; static char measures[MEASURES_COUNT][7] = {"n&ass", " Temp", " VOL"};
static char measures_custom[MEASURES_COUNT][7] = {"n&ass", " temp", "Volume"};
// Number of items in each category // Number of items in each category
#define WEIGHT_COUNT 4 #define WEIGHT_COUNT 4
@ -63,6 +66,12 @@ static const unit temps[TEMP_COUNT] = {
{"Gas Mk", 25., 25., 250}, {"Gas Mk", 25., 25., 250},
}; };
static const unit temps_custom[TEMP_COUNT] = {
{" #C", 1.8, 1.8, 32},
{" #F", 1., 1., 0}, // BASE
{"Gas Mk", 25., 25., 250},
};
static const unit vols[VOL_COUNT] = { static const unit vols[VOL_COUNT] = {
{" n&L", 1., 1., 0}, // BASE (ml) {" n&L", 1., 1., 0}, // BASE (ml)
{" L", 1000., 1000., 0}, {" L", 1000., 1000., 0},
@ -89,7 +98,7 @@ static void reset_state(kitchen_conversions_state_t *state)
state->to_is_us = movement_use_imperial_units(); state->to_is_us = movement_use_imperial_units();
state->selection_value = 0; state->selection_value = 0;
state->selection_index = 0; state->selection_index = 0;
state->light_held = false; state->alarm_held = false;
} }
void kitchen_conversions_face_setup(uint8_t watch_face_index, void **context_ptr) void kitchen_conversions_face_setup(uint8_t watch_face_index, void **context_ptr)
@ -111,7 +120,7 @@ void kitchen_conversions_face_activate(void *context)
// Handle any tasks related to your watch face coming on screen. // Handle any tasks related to your watch face coming on screen.
movement_request_tick_frequency(TICK_FREQ); movement_request_tick_frequency(TICK_FREQ);
reset_state(state, settings); reset_state(state);
} }
// Increments index pointer by 1, wrapping // Increments index pointer by 1, wrapping
@ -136,7 +145,7 @@ static unit *get_unit_list(uint8_t measurement_i)
return (unit *)weights; return (unit *)weights;
case TEMP: case TEMP:
return (unit *)temps; return (unit *)(watch_get_lcd_type() == WATCH_LCD_TYPE_CUSTOM ? temps_custom : temps);
case VOL: case VOL:
return (unit *)vols; return (unit *)vols;
@ -163,7 +172,11 @@ static void increment_input(kitchen_conversions_state_t *state)
// Displays the list of units in the selected category // Displays the list of units in the selected category
static void display_units(uint8_t measurement_i, uint8_t list_i) static void display_units(uint8_t measurement_i, uint8_t list_i)
{ {
watch_display_string(get_unit_list(measurement_i)[list_i].name, 4); // Slighly hacky way to improve ml display on new LCD
if (watch_get_lcd_type() == WATCH_LCD_TYPE_CUSTOM && measurement_i == VOL && list_i == 0)
watch_display_text(WATCH_POSITION_BOTTOM, " mL");
else
watch_display_text(WATCH_POSITION_BOTTOM, get_unit_list(measurement_i)[list_i].name);
} }
static void display(kitchen_conversions_state_t *state, uint8_t subsec) static void display(kitchen_conversions_state_t *state, uint8_t subsec)
@ -174,8 +187,9 @@ static void display(kitchen_conversions_state_t *state, uint8_t subsec)
{ {
case measurement: case measurement:
{ {
watch_display_string("Un", 0); watch_display_text_with_fallback(WATCH_POSITION_TOP, "Unit", "Un");
watch_display_string(measures[state->measurement_i], 4); char* measurement_name = (watch_get_lcd_type() == WATCH_LCD_TYPE_CUSTOM ? measures_custom : measures)[state->measurement_i];
watch_display_text(WATCH_POSITION_BOTTOM, measurement_name);
} }
break; break;
@ -185,14 +199,15 @@ static void display(kitchen_conversions_state_t *state, uint8_t subsec)
// Display Fr if non-locale specific, else display locale and F // Display Fr if non-locale specific, else display locale and F
if (state->measurement_i == VOL) if (state->measurement_i == VOL)
{ {
watch_display_string("F", 3); watch_display_text(WATCH_POSITION_TOP_RIGHT, " F");
char *locale_custom = state->from_is_us ? "USA" : "IMP";
char *locale = state->from_is_us ? "A " : "GB"; char *locale = state->from_is_us ? "A " : "GB";
watch_display_string(locale, 0); watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, locale_custom, locale);
} }
else else
{ {
watch_display_string("Fr", 0); watch_display_text_with_fallback(WATCH_POSITION_TOP, "Frm", "Fr");
} }
break; break;
@ -200,17 +215,17 @@ static void display(kitchen_conversions_state_t *state, uint8_t subsec)
case to: case to:
display_units(state->measurement_i, state->to_i); display_units(state->measurement_i, state->to_i);
// Display To if non-locale specific, else display locale and T // Display to if non-locale specific, else display locale and 't'
if (state->measurement_i == VOL) if (state->measurement_i == VOL) {
{ watch_display_text(WATCH_POSITION_TOP_RIGHT, " T");
watch_display_string("T", 3);
char *locale_custom = state->to_is_us ? "USA" : "IMP";
char *locale = state->to_is_us ? "A " : "GB"; char *locale = state->to_is_us ? "A " : "GB";
watch_display_string(locale, 0); watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, locale_custom, locale);
} }
else else
{ {
watch_display_string("To", 0); watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, " to", "to");
} }
break; break;
@ -218,22 +233,23 @@ static void display(kitchen_conversions_state_t *state, uint8_t subsec)
case input: case input:
{ {
char buf[7]; char buf[7];
sprintf(buf, "%06lu", state->selection_value); sprintf(buf, "%06u", state->selection_value);
watch_display_string(buf, 4); watch_display_text(WATCH_POSITION_BOTTOM, buf);
// Only allow ints for Gas Mk // Only allow ints for Gas Mk
if (state->measurement_i == TEMP && state->from_i == 2) if (state->measurement_i == TEMP && state->from_i == 2)
{ {
watch_display_string(" ", 8); watch_display_character(' ', 8);
watch_display_character(' ', 9);
} }
// Blink digit (on & off) twice a second // Blink digit (on & off) twice a second
if (subsec % 2) if (subsec % 2)
{ {
watch_display_string(" ", 4 + state->selection_index); watch_display_character(' ', 4 + state->selection_index);
} }
watch_display_string("In", 0); watch_display_text_with_fallback(WATCH_POSITION_TOP, "Input", "In");
} }
break; break;
@ -253,7 +269,7 @@ static void display(kitchen_conversions_state_t *state, uint8_t subsec)
if (conversion >= 1000000 || conversion < lower_bound) if (conversion >= 1000000 || conversion < lower_bound)
{ {
watch_set_indicator(WATCH_INDICATOR_BELL); watch_set_indicator(WATCH_INDICATOR_BELL);
watch_display_string("Err", 5); watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, " Error", " Err");
if (movement_button_should_sound()) if (movement_button_should_sound())
watch_buzzer_play_sequence(calc_fail_seq, NULL); watch_buzzer_play_sequence(calc_fail_seq, NULL);
@ -262,23 +278,24 @@ static void display(kitchen_conversions_state_t *state, uint8_t subsec)
{ {
uint32_t rounded = conversion + .5; uint32_t rounded = conversion + .5;
char buf[7]; char buf[7];
sprintf(buf, "%6lu", rounded); sprintf(buf, "%6u", rounded);
watch_display_string(buf, 4); watch_display_text(WATCH_POSITION_BOTTOM, buf);
// Make sure LSDs always filled // Make sure LSDs always filled
if (rounded < 10) if (rounded < 10)
{ {
watch_display_string("00", 7); watch_display_character('0', 7);
watch_display_character('0', 8);
} }
else if (rounded < 100) else if (rounded < 100)
{ {
watch_display_string("0", 7); watch_display_character('0', 7);
} }
if (movement_button_should_sound()) if (movement_button_should_sound())
watch_buzzer_play_sequence(calc_success_seq, NULL); watch_buzzer_play_sequence(calc_success_seq, NULL);
} }
watch_display_string("=", 1); watch_display_text_with_fallback(WATCH_POSITION_TOP, "Res =", " =");
} }
break; break;
@ -296,20 +313,20 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
{ {
case EVENT_ACTIVATE: case EVENT_ACTIVATE:
// Initial UI // Initial UI
display(state, settings, event.subsecond); display(state, event.subsecond);
break; break;
case EVENT_TICK: case EVENT_TICK:
// Update for blink animation on input // Update for blink animation on input
if (state->pg == input) if (state->pg == input)
{ {
display(state, settings, event.subsecond); display(state, event.subsecond);
// Increments input twice a second when light button held // Increments input twice a second when light button held
if (state->light_held && event.subsecond % 2) if (state->alarm_held && event.subsecond % 2)
increment_input(state); increment_input(state);
} }
break; break;
case EVENT_LIGHT_BUTTON_UP: case EVENT_ALARM_BUTTON_UP:
// Cycles options // Cycles options
switch (state->pg) switch (state->pg)
{ {
@ -335,13 +352,13 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
// Light button does nothing on final screen // Light button does nothing on final screen
if (state->pg != result) if (state->pg != result)
display(state, settings, event.subsecond); display(state, event.subsecond);
state->light_held = false; state->alarm_held = false;
break; break;
case EVENT_ALARM_BUTTON_UP: case EVENT_LIGHT_BUTTON_UP:
// Increments selected digit // Increments selected digit
if (state->pg == input) if (state->pg == input)
{ {
@ -355,7 +372,7 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
else else
{ {
state->pg++; state->pg++;
display(state, settings, event.subsecond); display(state, event.subsecond);
} }
} }
// Moves forward 1 page // Moves forward 1 page
@ -363,7 +380,7 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
{ {
if (state->pg == SCREEN_NUM - 1) if (state->pg == SCREEN_NUM - 1)
{ {
reset_state(state, settings); reset_state(state);
} }
else else
{ {
@ -375,13 +392,13 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
watch_buzzer_play_note(BUZZER_NOTE_C7, 50); watch_buzzer_play_note(BUZZER_NOTE_C7, 50);
} }
display(state, settings, event.subsecond); display(state, event.subsecond);
state->light_held = false; state->alarm_held = false;
break; break;
case EVENT_ALARM_LONG_PRESS: case EVENT_LIGHT_LONG_PRESS:
// Moves backwards through pages, resetting certain values // Moves backwards through pages, resetting certain values
if (state->pg != measurement) if (state->pg != measurement)
{ {
@ -415,17 +432,17 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
} }
state->pg--; state->pg--;
display(state, settings, event.subsecond); display(state, event.subsecond);
// Play beep // Play beep
if (movement_button_should_sound()) if (movement_button_should_sound())
watch_buzzer_play_note(BUZZER_NOTE_C8, 50); watch_buzzer_play_note(BUZZER_NOTE_C8, 50);
state->light_held = false; state->alarm_held = false;
} }
break; break;
case EVENT_LIGHT_LONG_PRESS: case EVENT_ALARM_LONG_PRESS:
// Switch between locales // Switch between locales
if (state->measurement_i == VOL) if (state->measurement_i == VOL)
{ {
@ -440,7 +457,7 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
if (state->pg == from || state->pg == to) if (state->pg == from || state->pg == to)
{ {
display(state, settings, event.subsecond); display(state, event.subsecond);
// Play bleep // Play bleep
if (movement_button_should_sound()) if (movement_button_should_sound())
@ -448,14 +465,14 @@ bool kitchen_conversions_face_loop(movement_event_t event, void *context)
} }
} }
// Sets flag to increment input digit when light held // Sets flag to increment input digit when alarm button held
if (state->pg == input) if (state->pg == input)
state->light_held = true; state->alarm_held = true;
break; break;
case EVENT_LIGHT_LONG_UP: case EVENT_ALARM_LONG_UP:
state->light_held = false; state->alarm_held = false;
break; break;
case EVENT_TIMEOUT: case EVENT_TIMEOUT:

View File

@ -33,13 +33,13 @@
* *
* How to use * How to use
* ---------- * ----------
* Short press the alarm button to move forward through menus, and long press to move backwards * Short press the light button to move forward through menus, and long press to move backwards
* *
* Press the light button to cycle through options in the menus * Press the alarm button to cycle through options in the menus
* *
* When inputting a number, the light button moves forward one place and the alarm button increments a digit by one * When inputting a number, the light button moves forward one place and the alarm button increments the value of the selected digit
* *
* To convert between Imperial (GB) and US (A) measurements of volume, hold the light button * To convert between Imperial (GB) and US (A) measurements of volume, hold the alarm button
* *
*/ */
@ -68,7 +68,7 @@ typedef struct
bool to_is_us; bool to_is_us;
uint32_t selection_value; uint32_t selection_value;
uint8_t selection_index; uint8_t selection_index;
bool light_held; bool alarm_held;
} kitchen_conversions_state_t; } kitchen_conversions_state_t;
void kitchen_conversions_face_setup(uint8_t watch_face_index, void **context_ptr); void kitchen_conversions_face_setup(uint8_t watch_face_index, void **context_ptr);