Skip to content

Commit 9258ec1

Browse files
committed
Add auto-repeat feature to Countdown watch face
1 parent b69cd11 commit 9258ec1

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

movement/watch_faces/complication/countdown_face.c

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* MIT License
33
*
4+
* Copyright (c) 2024 Joseph Bryant
45
* Copyright (c) 2023 Konrad Rieck
56
* Copyright (c) 2022 Wesley Ellis
67
*
@@ -68,17 +69,30 @@ static inline void button_beep(movement_settings_t *settings) {
6869
watch_buzzer_play_note(BUZZER_NOTE_C7, 50);
6970
}
7071

71-
static void start(countdown_state_t *state, movement_settings_t *settings) {
72-
watch_date_time now = watch_rtc_get_date_time();
72+
static void schedule_countdown(countdown_state_t *state, movement_settings_t *settings) {
7373

74-
state->mode = cd_running;
75-
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
76-
state->target_ts = watch_utility_offset_timestamp(state->now_ts, state->hours, state->minutes, state->seconds);
74+
// Calculate the new state->now_ts but don't update it until we've updated the target -
75+
// avoid possible race where the old target is compared to the new time and immediately triggers
76+
uint32_t new_now = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), get_tz_offset(settings));
77+
state->target_ts = watch_utility_offset_timestamp(new_now, state->hours, state->minutes, state->seconds);
78+
state->now_ts = new_now;
7779
watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, get_tz_offset(settings));
78-
movement_schedule_background_task(target_dt);
79-
watch_set_indicator(WATCH_INDICATOR_BELL);
80+
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
81+
}
82+
83+
static void auto_repeat(countdown_state_t *state, movement_settings_t *settings) {
84+
movement_play_alarm();
85+
load_countdown(state);
86+
schedule_countdown(state, settings);
8087
}
8188

89+
static void start(countdown_state_t *state, movement_settings_t *settings) {
90+
state->mode = cd_running;
91+
schedule_countdown(state, settings);
92+
}
93+
94+
95+
8296
static void draw(countdown_state_t *state, uint8_t subsecond) {
8397
char buf[16];
8498

@@ -100,7 +114,7 @@ static void draw(countdown_state_t *state, uint8_t subsecond) {
100114
break;
101115
case cd_reset:
102116
case cd_paused:
103-
watch_clear_indicator(WATCH_INDICATOR_BELL);
117+
watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
104118
sprintf(buf, "CD %2d%02d%02d", state->hours, state->minutes, state->seconds);
105119
break;
106120
case cd_setting:
@@ -127,13 +141,13 @@ static void draw(countdown_state_t *state, uint8_t subsecond) {
127141

128142
static void pause(countdown_state_t *state) {
129143
state->mode = cd_paused;
130-
movement_cancel_background_task();
131-
watch_clear_indicator(WATCH_INDICATOR_BELL);
144+
movement_cancel_background_task_for_face(state->watch_face_index);
145+
watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
132146
}
133147

134148
static void reset(countdown_state_t *state) {
135149
state->mode = cd_reset;
136-
movement_cancel_background_task();
150+
movement_cancel_background_task_for_face(state->watch_face_index);
137151
load_countdown(state);
138152
}
139153

@@ -142,6 +156,15 @@ static void ring(countdown_state_t *state) {
142156
reset(state);
143157
}
144158

159+
static void times_up(movement_settings_t *settings, countdown_state_t *state) {
160+
if(state->repeat) {
161+
auto_repeat(state, settings);
162+
}
163+
else {
164+
ring(state);
165+
}
166+
}
167+
145168
static void settings_increment(countdown_state_t *state) {
146169
switch(state->selection) {
147170
case 0:
@@ -170,6 +193,7 @@ void countdown_face_setup(movement_settings_t *settings, uint8_t watch_face_inde
170193
memset(*context_ptr, 0, sizeof(countdown_state_t));
171194
state->minutes = DEFAULT_MINUTES;
172195
state->mode = cd_reset;
196+
state->watch_face_index = watch_face_index;
173197
store_countdown(state);
174198
}
175199
}
@@ -180,9 +204,11 @@ void countdown_face_activate(movement_settings_t *settings, void *context) {
180204
if(state->mode == cd_running) {
181205
watch_date_time now = watch_rtc_get_date_time();
182206
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
183-
watch_set_indicator(WATCH_INDICATOR_BELL);
207+
watch_set_indicator(WATCH_INDICATOR_SIGNAL);
184208
}
185209
watch_set_colon();
210+
if(state->repeat)
211+
watch_set_indicator(WATCH_INDICATOR_BELL);
186212

187213
movement_request_tick_frequency(1);
188214
quick_ticks_running = false;
@@ -252,6 +278,7 @@ bool countdown_face_loop(movement_event_t event, movement_settings_t *settings,
252278
// Only start the timer if we have a valid time.
253279
start(state, settings);
254280
button_beep(settings);
281+
watch_set_indicator(WATCH_INDICATOR_SIGNAL);
255282
}
256283
break;
257284
case cd_setting:
@@ -261,9 +288,19 @@ bool countdown_face_loop(movement_event_t event, movement_settings_t *settings,
261288
draw(state, event.subsecond);
262289
break;
263290
case EVENT_ALARM_LONG_PRESS:
264-
if (state->mode == cd_setting) {
265-
quick_ticks_running = true;
266-
movement_request_tick_frequency(8);
291+
switch(state->mode) {
292+
case cd_setting:
293+
quick_ticks_running = true;
294+
movement_request_tick_frequency(8);
295+
break;
296+
default:
297+
// Toggle auto-repeat
298+
button_beep(settings);
299+
state->repeat = !state->repeat;
300+
if(state->repeat)
301+
watch_set_indicator(WATCH_INDICATOR_BELL);
302+
else
303+
watch_clear_indicator(WATCH_INDICATOR_BELL);
267304
}
268305
break;
269306
case EVENT_LIGHT_LONG_PRESS:
@@ -285,7 +322,7 @@ bool countdown_face_loop(movement_event_t event, movement_settings_t *settings,
285322
abort_quick_ticks(state);
286323
break;
287324
case EVENT_BACKGROUND_TASK:
288-
ring(state);
325+
times_up(settings, state);
289326
break;
290327
case EVENT_TIMEOUT:
291328
abort_quick_ticks(state);

movement/watch_faces/complication/countdown_face.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ typedef struct {
6262
uint8_t set_seconds;
6363
uint8_t selection;
6464
countdown_mode_t mode;
65+
bool repeat;
66+
uint8_t watch_face_index;
6567
} countdown_state_t;
6668

6769

0 commit comments

Comments
 (0)