Kitchen Conversions Face
This commit is contained in:
parent
91c82ee5f2
commit
1b90a4a07a
@ -121,6 +121,7 @@ SRCS += \
|
|||||||
../watch_faces/complication/couch_to_5k_face.c \
|
../watch_faces/complication/couch_to_5k_face.c \
|
||||||
../watch_faces/clock/minute_repeater_decimal_face.c \
|
../watch_faces/clock/minute_repeater_decimal_face.c \
|
||||||
../watch_faces/complication/tuning_tones_face.c \
|
../watch_faces/complication/tuning_tones_face.c \
|
||||||
|
../watch_faces/complication/kitchen_conversions_face.c \
|
||||||
# New watch faces go above this line.
|
# New watch faces go above this line.
|
||||||
|
|
||||||
# Leave this line at the bottom of the file; it has all the targets for making your project.
|
# Leave this line at the bottom of the file; it has all the targets for making your project.
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
#include "couch_to_5k_face.h"
|
#include "couch_to_5k_face.h"
|
||||||
#include "minute_repeater_decimal_face.h"
|
#include "minute_repeater_decimal_face.h"
|
||||||
#include "tuning_tones_face.h"
|
#include "tuning_tones_face.h"
|
||||||
|
#include "kitchen_conversions_face.h"
|
||||||
// New includes go above this line.
|
// New includes go above this line.
|
||||||
|
|
||||||
#endif // MOVEMENT_FACES_H_
|
#endif // MOVEMENT_FACES_H_
|
||||||
|
480
movement/watch_faces/complication/kitchen_conversions_face.c
Normal file
480
movement/watch_faces/complication/kitchen_conversions_face.c
Normal file
@ -0,0 +1,480 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 PrimmR
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "kitchen_conversions_face.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[6]; // Name to display on selection
|
||||||
|
double conv_factor_uk; // Unit as represented in base units (UK)
|
||||||
|
double conv_factor_us; // Unit as represented in base units (US)
|
||||||
|
int16_t linear_factor; // Addition of constant (For temperatures)
|
||||||
|
} unit;
|
||||||
|
|
||||||
|
#define TICK_FREQ 4
|
||||||
|
|
||||||
|
#define MEASURES_COUNT 3 // Number of different measurement 'types'
|
||||||
|
#define WEIGHT 0
|
||||||
|
#define TEMP 1
|
||||||
|
#define VOL 2
|
||||||
|
|
||||||
|
// Names of measurements
|
||||||
|
static char measures[MEASURES_COUNT][6] = {"WeIght", " Temp", " VOL"};
|
||||||
|
|
||||||
|
// Number of items in each category
|
||||||
|
#define WEIGHT_COUNT 4
|
||||||
|
#define TEMP_COUNT 3
|
||||||
|
#define VOL_COUNT 9
|
||||||
|
const uint8_t units_count[4] = {WEIGHT_COUNT, TEMP_COUNT, VOL_COUNT};
|
||||||
|
|
||||||
|
static const unit weights[WEIGHT_COUNT] = {
|
||||||
|
{" g", 1., 1., 0}, // BASE
|
||||||
|
{" kg", 1000., 1000, 0},
|
||||||
|
{"Ounce", 28.34952, 28.34952, 0},
|
||||||
|
{" Pound", 453.5924, 453.5924, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unit temps[TEMP_COUNT] = {
|
||||||
|
{" # C", 1.8, 1.8, 32},
|
||||||
|
{" # F", 1., 1., 0}, // BASE
|
||||||
|
{"Gas Mk", 25., 25., 250},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unit vols[VOL_COUNT] = {
|
||||||
|
{" n&L", 1., 1., 0}, // BASE (ml)
|
||||||
|
{" L", 1000., 1000., 0},
|
||||||
|
{" Fl Oz", 28.41306, 29.57353, 0},
|
||||||
|
{" Tbsp", 17.75816, 14.78677, 0},
|
||||||
|
{" Tsp", 5.919388, 4.928922, 0},
|
||||||
|
{" Cup", 284.1306, 236.5882, 0},
|
||||||
|
{" Pint", 568.2612, 473.1765, 0},
|
||||||
|
{" Quart", 1136.522, 946.353, 0},
|
||||||
|
{"Gallon", 4546.09, 3785.412, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int8_t calc_success_seq[5] = {BUZZER_NOTE_G6, 10, BUZZER_NOTE_C7, 10, 0};
|
||||||
|
static int8_t calc_fail_seq[5] = {BUZZER_NOTE_C7, 10, BUZZER_NOTE_G6, 10, 0};
|
||||||
|
|
||||||
|
// Resets all state variables to 0
|
||||||
|
static void reset_state(kitchen_conversions_state_t *state, movement_settings_t *settings)
|
||||||
|
{
|
||||||
|
state->pg = measurement;
|
||||||
|
state->measurement_i = 0;
|
||||||
|
state->from_i = 0;
|
||||||
|
state->from_is_us = settings->bit.use_imperial_units; // If uses imperial, most likely to be US
|
||||||
|
state->to_i = 0;
|
||||||
|
state->to_is_us = settings->bit.use_imperial_units;
|
||||||
|
state->selection_value = 0;
|
||||||
|
state->selection_index = 0;
|
||||||
|
state->light_held = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kitchen_conversions_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void **context_ptr)
|
||||||
|
{
|
||||||
|
(void)settings;
|
||||||
|
(void)watch_face_index;
|
||||||
|
if (*context_ptr == NULL)
|
||||||
|
{
|
||||||
|
*context_ptr = malloc(sizeof(kitchen_conversions_state_t));
|
||||||
|
memset(*context_ptr, 0, sizeof(kitchen_conversions_state_t));
|
||||||
|
// Do any one-time tasks in here; the inside of this conditional happens only at boot.
|
||||||
|
}
|
||||||
|
// Do any pin or peripheral setup here; this will be called whenever the watch wakes from deep sleep.
|
||||||
|
}
|
||||||
|
|
||||||
|
void kitchen_conversions_face_activate(movement_settings_t *settings, void *context)
|
||||||
|
{
|
||||||
|
(void)settings;
|
||||||
|
kitchen_conversions_state_t *state = (kitchen_conversions_state_t *)context;
|
||||||
|
|
||||||
|
// Handle any tasks related to your watch face coming on screen.
|
||||||
|
movement_request_tick_frequency(TICK_FREQ);
|
||||||
|
|
||||||
|
reset_state(state, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increments index pointer by 1, wrapping
|
||||||
|
#define increment_wrapping(index, wrap) ({(index)++; index %= wrap; })
|
||||||
|
|
||||||
|
static uint32_t pow_10(uint8_t n)
|
||||||
|
{
|
||||||
|
uint32_t result = 1;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
result *= 10;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns correct list of units for the measurement index
|
||||||
|
static unit *get_unit_list(uint8_t measurement_i)
|
||||||
|
{
|
||||||
|
switch (measurement_i)
|
||||||
|
{
|
||||||
|
case WEIGHT:
|
||||||
|
return (unit *)weights;
|
||||||
|
|
||||||
|
case TEMP:
|
||||||
|
return (unit *)temps;
|
||||||
|
|
||||||
|
case VOL:
|
||||||
|
return (unit *)vols;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (unit *)weights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment digit by 1 in input (wraps)
|
||||||
|
static void increment_input(kitchen_conversions_state_t *state)
|
||||||
|
{
|
||||||
|
uint8_t digit = state->selection_value / pow_10(DISPLAY_DIGITS - 1 - state->selection_index) % 10;
|
||||||
|
if (digit != 9)
|
||||||
|
{
|
||||||
|
state->selection_value += pow_10(DISPLAY_DIGITS - 1 - state->selection_index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->selection_value -= 9 * pow_10(DISPLAY_DIGITS - 1 - state->selection_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Displays the list of units in the selected category
|
||||||
|
static void display_units(uint8_t measurement_i, uint8_t list_i)
|
||||||
|
{
|
||||||
|
watch_display_string(get_unit_list(measurement_i)[list_i].name, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void display(kitchen_conversions_state_t *state, movement_settings_t *settings, uint8_t subsec)
|
||||||
|
{
|
||||||
|
watch_clear_display();
|
||||||
|
|
||||||
|
switch (state->pg)
|
||||||
|
{
|
||||||
|
case measurement:
|
||||||
|
{
|
||||||
|
watch_display_string("Un", 0);
|
||||||
|
watch_display_string(measures[state->measurement_i], 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case from:
|
||||||
|
display_units(state->measurement_i, state->from_i);
|
||||||
|
|
||||||
|
// Display Fr if non-locale specific, else display locale and F
|
||||||
|
if (state->measurement_i == VOL)
|
||||||
|
{
|
||||||
|
watch_display_string("F", 3);
|
||||||
|
|
||||||
|
char *locale = state->from_is_us ? "A " : "GB";
|
||||||
|
watch_display_string(locale, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
watch_display_string("Fr", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case to:
|
||||||
|
display_units(state->measurement_i, state->to_i);
|
||||||
|
|
||||||
|
// Display To if non-locale specific, else display locale and T
|
||||||
|
if (state->measurement_i == VOL)
|
||||||
|
{
|
||||||
|
watch_display_string("T", 3);
|
||||||
|
|
||||||
|
char *locale = state->to_is_us ? "A " : "GB";
|
||||||
|
watch_display_string(locale, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
watch_display_string("To", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case input:
|
||||||
|
{
|
||||||
|
char buf[7];
|
||||||
|
sprintf(buf, "%06lu", state->selection_value);
|
||||||
|
watch_display_string(buf, 4);
|
||||||
|
|
||||||
|
// Only allow ints for Gas Mk
|
||||||
|
if (state->measurement_i == TEMP && state->from_i == 2)
|
||||||
|
{
|
||||||
|
watch_display_string(" ", 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blink digit (on & off) twice a second
|
||||||
|
if (subsec % 2)
|
||||||
|
{
|
||||||
|
watch_display_string(" ", 4 + state->selection_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_display_string("In", 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case result:
|
||||||
|
{
|
||||||
|
unit froms = get_unit_list(state->measurement_i)[state->from_i];
|
||||||
|
unit tos = get_unit_list(state->measurement_i)[state->to_i];
|
||||||
|
// Chooses correct factor for locale
|
||||||
|
double f_conv_factor = state->from_is_us ? froms.conv_factor_us : froms.conv_factor_uk;
|
||||||
|
double t_conv_factor = state->to_is_us ? tos.conv_factor_us : tos.conv_factor_uk;
|
||||||
|
// Converts
|
||||||
|
double to_base = (state->selection_value * f_conv_factor) + 100 * froms.linear_factor;
|
||||||
|
double conversion = ((to_base - 100 * tos.linear_factor) / t_conv_factor);
|
||||||
|
|
||||||
|
// If number too large or too small
|
||||||
|
uint8_t lower_bound = (state->measurement_i == TEMP && state->to_i == 2) ? 100 : 0;
|
||||||
|
if (conversion >= 1000000 || conversion < lower_bound)
|
||||||
|
{
|
||||||
|
watch_set_indicator(WATCH_INDICATOR_BELL);
|
||||||
|
watch_display_string("Err", 5);
|
||||||
|
|
||||||
|
if (settings->bit.button_should_sound)
|
||||||
|
watch_buzzer_play_sequence(calc_fail_seq, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t rounded = conversion + .5;
|
||||||
|
char buf[7];
|
||||||
|
sprintf(buf, "%6lu", rounded);
|
||||||
|
watch_display_string(buf, 4);
|
||||||
|
|
||||||
|
// Make sure LSDs always filled
|
||||||
|
if (rounded < 10)
|
||||||
|
{
|
||||||
|
watch_display_string("00", 7);
|
||||||
|
}
|
||||||
|
else if (rounded < 100)
|
||||||
|
{
|
||||||
|
watch_display_string("0", 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->bit.button_should_sound)
|
||||||
|
watch_buzzer_play_sequence(calc_success_seq, NULL);
|
||||||
|
}
|
||||||
|
watch_display_string("=", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool kitchen_conversions_face_loop(movement_event_t event, movement_settings_t *settings, void *context)
|
||||||
|
{
|
||||||
|
kitchen_conversions_state_t *state = (kitchen_conversions_state_t *)context;
|
||||||
|
|
||||||
|
switch (event.event_type)
|
||||||
|
{
|
||||||
|
case EVENT_ACTIVATE:
|
||||||
|
// Initial UI
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
break;
|
||||||
|
case EVENT_TICK:
|
||||||
|
// Update for blink animation on input
|
||||||
|
if (state->pg == input)
|
||||||
|
{
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
|
||||||
|
// Increments input twice a second when light button held
|
||||||
|
if (state->light_held && event.subsecond % 2)
|
||||||
|
increment_input(state);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EVENT_LIGHT_BUTTON_UP:
|
||||||
|
// Cycles options
|
||||||
|
switch (state->pg)
|
||||||
|
{
|
||||||
|
case measurement:
|
||||||
|
increment_wrapping(state->measurement_i, MEASURES_COUNT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case from:
|
||||||
|
increment_wrapping(state->from_i, units_count[state->measurement_i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case to:
|
||||||
|
increment_wrapping(state->to_i, units_count[state->measurement_i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case input:
|
||||||
|
increment_input(state);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light button does nothing on final screen
|
||||||
|
if (state->pg != result)
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
|
||||||
|
state->light_held = false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_ALARM_BUTTON_UP:
|
||||||
|
// Increments selected digit
|
||||||
|
if (state->pg == input)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Moves between digits in input
|
||||||
|
// Wraps at 6 digits unless gas mark selected
|
||||||
|
if (state->selection_index < (DISPLAY_DIGITS - 1) - 2 * (state->measurement_i == TEMP && state->from_i == 2))
|
||||||
|
{
|
||||||
|
state->selection_index++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->pg++;
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Moves forward 1 page
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (state->pg == SCREEN_NUM - 1)
|
||||||
|
{
|
||||||
|
reset_state(state, settings);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state->pg++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play boop
|
||||||
|
if (settings->bit.button_should_sound)
|
||||||
|
watch_buzzer_play_note(BUZZER_NOTE_C7, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
|
||||||
|
state->light_held = false;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_ALARM_LONG_PRESS:
|
||||||
|
// Moves backwards through pages, resetting certain values
|
||||||
|
if (state->pg != measurement)
|
||||||
|
{
|
||||||
|
switch (state->pg)
|
||||||
|
{
|
||||||
|
case measurement:
|
||||||
|
state->measurement_i = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case from:
|
||||||
|
state->from_i = 0;
|
||||||
|
state->from_is_us = settings->bit.use_imperial_units;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case to:
|
||||||
|
state->to_i = 0;
|
||||||
|
state->to_is_us = settings->bit.use_imperial_units;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case input:
|
||||||
|
state->selection_index = 0;
|
||||||
|
state->selection_value = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case result:
|
||||||
|
state->selection_index = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->pg--;
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
|
||||||
|
// Play beep
|
||||||
|
if (settings->bit.button_should_sound)
|
||||||
|
watch_buzzer_play_note(BUZZER_NOTE_C8, 50);
|
||||||
|
|
||||||
|
state->light_held = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_LIGHT_LONG_PRESS:
|
||||||
|
// Switch between locales
|
||||||
|
if (state->measurement_i == VOL)
|
||||||
|
{
|
||||||
|
if (state->pg == from)
|
||||||
|
{
|
||||||
|
state->from_is_us = !state->from_is_us;
|
||||||
|
}
|
||||||
|
else if (state->pg == to)
|
||||||
|
{
|
||||||
|
state->to_is_us = !state->to_is_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->pg == from || state->pg == to)
|
||||||
|
{
|
||||||
|
display(state, settings, event.subsecond);
|
||||||
|
|
||||||
|
// Play bleep
|
||||||
|
if (settings->bit.button_should_sound)
|
||||||
|
watch_buzzer_play_note(BUZZER_NOTE_E7, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets flag to increment input digit when light held
|
||||||
|
if (state->pg == input)
|
||||||
|
state->light_held = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_LIGHT_LONG_UP:
|
||||||
|
state->light_held = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_TIMEOUT:
|
||||||
|
movement_move_to_face(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return movement_default_loop_handler(event, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kitchen_conversions_face_resign(movement_settings_t *settings, void *context)
|
||||||
|
{
|
||||||
|
(void)settings;
|
||||||
|
(void)context;
|
||||||
|
|
||||||
|
// handle any cleanup before your watch face goes off-screen.
|
||||||
|
}
|
87
movement/watch_faces/complication/kitchen_conversions_face.h
Normal file
87
movement/watch_faces/complication/kitchen_conversions_face.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 PrimmR
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KITCHEN_CONVERSIONS_FACE_H_
|
||||||
|
#define KITCHEN_CONVERSIONS_FACE_H_
|
||||||
|
|
||||||
|
#include "movement.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kitchen Conversions
|
||||||
|
* A face that allows the user to convert between common kitchen units of measurement
|
||||||
|
*
|
||||||
|
* How to use
|
||||||
|
* ----------
|
||||||
|
* Short press the alarm button to move forward through menus, and long press to move backwards
|
||||||
|
*
|
||||||
|
* Press the light 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
|
||||||
|
*
|
||||||
|
* To convert between Imperial (GB) and US (A) measurements of volume, hold the light button
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SCREEN_NUM 5
|
||||||
|
|
||||||
|
// Names of each page
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
measurement,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
input,
|
||||||
|
result,
|
||||||
|
} page_t;
|
||||||
|
|
||||||
|
#define DISPLAY_DIGITS 6
|
||||||
|
|
||||||
|
// Settings when app is running
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
page_t pg;
|
||||||
|
uint8_t measurement_i;
|
||||||
|
uint8_t from_i;
|
||||||
|
bool from_is_us;
|
||||||
|
uint8_t to_i;
|
||||||
|
bool to_is_us;
|
||||||
|
uint32_t selection_value;
|
||||||
|
uint8_t selection_index;
|
||||||
|
bool light_held;
|
||||||
|
} kitchen_conversions_state_t;
|
||||||
|
|
||||||
|
void kitchen_conversions_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void **context_ptr);
|
||||||
|
void kitchen_conversions_face_activate(movement_settings_t *settings, void *context);
|
||||||
|
bool kitchen_conversions_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
|
||||||
|
void kitchen_conversions_face_resign(movement_settings_t *settings, void *context);
|
||||||
|
|
||||||
|
#define kitchen_conversions_face ((const watch_face_t){ \
|
||||||
|
kitchen_conversions_face_setup, \
|
||||||
|
kitchen_conversions_face_activate, \
|
||||||
|
kitchen_conversions_face_loop, \
|
||||||
|
kitchen_conversions_face_resign, \
|
||||||
|
NULL, \
|
||||||
|
})
|
||||||
|
|
||||||
|
#endif // KITCHEN_CONVERSIONS_FACE_H_
|
Loading…
x
Reference in New Issue
Block a user