updated countdown timer, new apps orgasmotron and yatzee, and formatting on all and GPIO Reader 2

This commit is contained in:
RogueMaster
2022-12-16 15:40:14 -05:00
parent 9cb7e75029
commit 28afd483df
22 changed files with 1837 additions and 145 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ CountDownTimerApp* countdown_app_new(void) {
// 2.3 attach views to the dispatcher
// helloworld view
app->helloworld_view = helloworld_view_new();
app->helloworld_view = countdown_timer_view_new();
register_view(app->view_dispatcher, countdown_timer_view_get_view(app->helloworld_view), 0xff);
// 2.5 switch to default view
@@ -1,23 +1,6 @@
#include <furi.h>
#include "utils.h"
static const NotificationSequence sequence_finish = {
&message_display_backlight_on,
&message_blue_255,
&message_vibro_on,
&message_note_c5,
&message_delay_250,
&message_note_c5,
&message_delay_500,
&message_note_c5,
&message_delay_100,
&message_note_c5,
&message_delay_500,
&message_sound_off,
&message_vibro_off,
&message_delay_250,
NULL,
};
static const NotificationSequence sequence_beep = {
&message_blue_255,
&message_note_d5,
@@ -37,5 +20,15 @@ void notification_off() {
}
void notification_timeup() {
notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_finish);
notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_audiovisual_alert);
}
void parse_sec_to_time_str(char* buffer, size_t len, int32_t sec) {
snprintf(
buffer,
len,
"%02ld:%02ld:%02ld",
(sec % (60 * 60 * 24)) / (60 * 60), // hour
(sec % (60 * 60)) / 60, // minute
sec % 60); // second
}
@@ -7,4 +7,6 @@ void notification_beep_once();
void notification_off();
void notification_timeup();
void parse_sec_to_time_str(char* buffer, size_t len, int32_t sec);
#endif // __UTILS_H__
@@ -2,75 +2,87 @@
#include "../utils/utils.h"
// internal
static void handle_cmd(CountDownTimView* hw, CountDownViewCmd cmd);
static void handle_time_setting_updown(CountDownTimView* hwv, CountDownViewCmd cmd);
static void handle_time_setting_select(InputKey key, CountDownTimView* hwv);
static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd);
static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd);
static void handle_time_setting_select(InputKey key, CountDownTimView* cdv);
static void draw_selection(Canvas* canvas, CountDownViewSelect selection);
static void countdown_timer_start_counting(CountDownTimView* cdv);
static void countdown_timer_pause_counting(CountDownTimView* cdv);
// callbacks
static void countdown_timer_view_on_enter(void* ctx);
static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx);
static bool countdown_timer_view_on_input(InputEvent* event, void* ctx);
static void timer_cb(void* ctx);
CountDownTimView* helloworld_view_new() {
CountDownTimView* hwv = (CountDownTimView*)(malloc(sizeof(CountDownTimView)));
CountDownTimView* countdown_timer_view_new() {
CountDownTimView* cdv = (CountDownTimView*)(malloc(sizeof(CountDownTimView)));
hwv->view = view_alloc();
cdv->view = view_alloc();
hwv->timer = furi_timer_alloc(timer_cb, FuriTimerTypePeriodic, hwv);
cdv->timer = furi_timer_alloc(timer_cb, FuriTimerTypePeriodic, cdv);
hwv->counting = false;
cdv->counting = false;
view_set_context(hwv->view, hwv);
view_set_context(cdv->view, cdv);
view_allocate_model(hwv->view, ViewModelTypeLocking, sizeof(CountDownModel));
view_allocate_model(cdv->view, ViewModelTypeLocking, sizeof(CountDownModel));
view_set_draw_callback(hwv->view, countdown_timer_view_on_draw);
view_set_input_callback(hwv->view, countdown_timer_view_on_input);
view_set_enter_callback(hwv->view, countdown_timer_view_on_enter);
view_set_draw_callback(cdv->view, countdown_timer_view_on_draw);
view_set_input_callback(cdv->view, countdown_timer_view_on_input);
view_set_enter_callback(cdv->view, countdown_timer_view_on_enter);
return hwv;
return cdv;
}
void countdown_timer_view_delete(CountDownTimView* hwv) {
furi_assert(hwv);
void countdown_timer_view_delete(CountDownTimView* cdv) {
furi_assert(cdv);
view_free(hwv->view);
furi_timer_stop(hwv->timer);
furi_timer_free(hwv->timer);
view_free(cdv->view);
furi_timer_stop(cdv->timer);
furi_timer_free(cdv->timer);
free(hwv);
free(cdv);
}
View* countdown_timer_view_get_view(CountDownTimView* hwv) {
return hwv->view;
View* countdown_timer_view_get_view(CountDownTimView* cdv) {
return cdv->view;
}
void countdown_timer_view_state_reset(CountDownTimView* hwv) {
hwv->counting = false;
void countdown_timer_view_state_reset(CountDownTimView* cdv) {
cdv->counting = false;
with_view_model(
hwv->view, CountDownModel * model, { model->sec_expected = 10; }, true);
cdv->view, CountDownModel * model, { model->count = model->saved_count_setting; }, true)
}
void countdown_timer_state_toggle(CountDownTimView* hwv) {
bool on = hwv->counting;
void countdown_timer_state_toggle(CountDownTimView* cdv) {
bool on = cdv->counting;
if(!on) {
furi_timer_start(hwv->timer, furi_kernel_get_tick_frequency() * 1); // 1s
countdown_timer_start_counting(cdv);
} else {
furi_timer_stop(hwv->timer);
notification_off();
countdown_timer_pause_counting(cdv);
}
hwv->counting = !on;
cdv->counting = !on;
}
// on enter callback, CountDownTimView as ctx
static void countdown_timer_view_on_enter(void* ctx) {
furi_assert(ctx);
CountDownTimView* hwv = (CountDownTimView*)ctx;
countdown_timer_view_state_reset(hwv);
CountDownTimView* cdv = (CountDownTimView*)ctx;
// set current count to a initial value
with_view_model(
cdv->view,
CountDownModel * model,
{
model->count = INIT_COUNT;
model->saved_count_setting = INIT_COUNT;
},
true);
}
// view draw callback, CountDownModel as ctx
@@ -80,23 +92,21 @@ static void countdown_timer_view_on_draw(Canvas* canvas, void* ctx) {
char buffer[64];
int32_t sec = model->sec_expected;
int32_t count = model->count;
int32_t expected_count = model->saved_count_setting;
CountDownViewSelect select = model->select;
elements_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// elements_frame(canvas, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
canvas_set_font(canvas, FontBigNumbers);
draw_selection(canvas, select);
snprintf(
buffer,
sizeof(buffer),
"%02ld:%02ld:%02ld",
(sec % (60 * 60 * 24)) / (60 * 60), // hour
(sec % (60 * 60)) / 60, // minute
sec % 60); // second
parse_sec_to_time_str(buffer, sizeof(buffer), count);
canvas_draw_str_aligned(
canvas, SCREEN_CENTER_X, SCREEN_CENTER_Y, AlignCenter, AlignCenter, buffer);
elements_progress_bar(canvas, 0, 0, SCREEN_WIDTH, (1.0 * count / expected_count));
}
// keys input event callback, CountDownTimView as ctx
@@ -116,7 +126,7 @@ static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) {
case InputKeyOk:
if(event->type == InputTypeShort) {
handle_cmd(hw, CountDownTimerToggleCounting);
handle_misc_cmd(hw, CountDownTimerToggleCounting);
}
break;
@@ -130,7 +140,7 @@ static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) {
if(event->type == InputTypeLong) {
switch(event->key) {
case InputKeyOk:
handle_cmd(hw, CountDownTimerReset);
handle_misc_cmd(hw, CountDownTimerReset);
break;
case InputKeyBack:
@@ -150,75 +160,79 @@ static bool countdown_timer_view_on_input(InputEvent* event, void* ctx) {
static void timer_cb(void* ctx) {
furi_assert(ctx);
CountDownTimView* hwv = (CountDownTimView*)ctx;
CountDownTimView* cdv = (CountDownTimView*)ctx;
int32_t sec;
int32_t count;
bool timeup = false;
// decrement counter
with_view_model(
hwv->view,
cdv->view,
CountDownModel * model,
{
sec = model->sec_expected;
sec--;
count = model->count;
count--;
// check timeup
if(sec <= 0) {
sec = 0;
if(count <= 0) {
count = 0;
timeup = true;
}
model->sec_expected = sec;
model->count = count;
},
true);
if(timeup) {
handle_cmd(hwv, CountDownTimerTimeUp);
handle_misc_cmd(cdv, CountDownTimerTimeUp);
}
}
static void handle_time_setting_updown(CountDownTimView* hwv, CountDownViewCmd cmd) {
int32_t sec_expected;
static void handle_time_setting_updown(CountDownTimView* cdv, CountDownViewCmd cmd) {
int32_t count;
with_view_model(
hwv->view,
cdv->view,
CountDownModel * model,
{
sec_expected = model->sec_expected;
count = model->count;
switch(cmd) {
case CountDownTimerMinuteUp:
sec_expected += 60;
count += 60;
break;
case CountDownTimerMinuteDown:
sec_expected -= 60;
count -= 60;
break;
case CountDownTimerHourDown:
sec_expected -= 3600;
count -= 3600;
break;
case CountDownTimerHourUp:
sec_expected += 3600;
count += 3600;
break;
case CountDownTimerSecUp:
sec_expected++;
count++;
break;
case CountDownTimerSecDown:
sec_expected--;
count--;
break;
default:
break;
}
if(sec_expected < 0) {
sec_expected = 0;
if(count < 0) {
count = 0;
}
model->sec_expected = sec_expected;
// update count state
model->count = count;
// save the count time setting
model->saved_count_setting = count;
},
true);
}
static void handle_cmd(CountDownTimView* hw, CountDownViewCmd cmd) {
static void handle_misc_cmd(CountDownTimView* hw, CountDownViewCmd cmd) {
switch(cmd) {
case CountDownTimerTimeUp:
notification_timeup();
@@ -242,8 +256,8 @@ static void handle_cmd(CountDownTimView* hw, CountDownViewCmd cmd) {
return;
}
static void handle_time_setting_select(InputKey key, CountDownTimView* hwv) {
bool counting = hwv->counting;
static void handle_time_setting_select(InputKey key, CountDownTimView* cdv) {
bool counting = cdv->counting;
CountDownViewCmd setting_cmd = CountDownTimerSecUp;
CountDownViewSelect selection;
@@ -253,7 +267,7 @@ static void handle_time_setting_select(InputKey key, CountDownTimView* hwv) {
// load current selection from model context
with_view_model(
hwv->view, CountDownModel * model, { selection = model->select; }, false);
cdv->view, CountDownModel * model, { selection = model->select; }, false);
// select
switch(key) {
@@ -270,7 +284,7 @@ static void handle_time_setting_select(InputKey key, CountDownTimView* hwv) {
break;
}
handle_time_setting_updown(hwv, setting_cmd);
handle_time_setting_updown(cdv, setting_cmd);
break;
case InputKeyDown:
@@ -286,7 +300,7 @@ static void handle_time_setting_select(InputKey key, CountDownTimView* hwv) {
break;
}
handle_time_setting_updown(hwv, setting_cmd);
handle_time_setting_updown(cdv, setting_cmd);
break;
case InputKeyRight:
@@ -305,19 +319,28 @@ static void handle_time_setting_select(InputKey key, CountDownTimView* hwv) {
// save selection to model context
with_view_model(
hwv->view, CountDownModel * model, { model->select = selection; }, false);
cdv->view, CountDownModel * model, { model->select = selection; }, false);
}
static void draw_selection(Canvas* canvas, CountDownViewSelect selection) {
switch(selection) {
case CountDownTimerSelectSec:
elements_slightly_rounded_box(canvas, SCREEN_CENTER_X + 25, SCREEN_CENTER_Y + 11, 21, 2);
elements_slightly_rounded_box(canvas, SCREEN_CENTER_X + 25, SCREEN_CENTER_Y + 11, 24, 2);
break;
case CountDownTimerSelectMinute:
elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 10, SCREEN_CENTER_Y + 11, 21, 2);
break;
case CountDownTimerSelectHour:
elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 47, SCREEN_CENTER_Y + 11, 21, 2);
elements_slightly_rounded_box(canvas, SCREEN_CENTER_X - 47, SCREEN_CENTER_Y + 11, 24, 2);
break;
}
}
static void countdown_timer_start_counting(CountDownTimView* cdv) {
furi_timer_start(cdv->timer, furi_kernel_get_tick_frequency() * 1); // 1s
}
static void countdown_timer_pause_counting(CountDownTimView* cdv) {
furi_timer_stop(cdv->timer);
notification_off();
}
@@ -11,9 +11,7 @@
#define SCREEN_CENTER_X (SCREEN_WIDTH / 2)
#define SCREEN_CENTER_Y (SCREEN_HEIGHT / 2)
#define MAX_SCALE 80
#define MAX_MOVE_STEP 16
#define MIN_MOVE_STEP 2
#define INIT_COUNT 10
typedef enum {
CountDownTimerMinuteUp,
@@ -34,8 +32,9 @@ typedef enum {
} CountDownViewSelect;
typedef struct {
int32_t sec_expected;
uint8_t select; // setting
int32_t count;
int32_t saved_count_setting;
CountDownViewSelect select; // setting
} CountDownModel;
typedef struct {
@@ -47,14 +46,14 @@ typedef struct {
// functions
// allocate helloworld view
CountDownTimView* helloworld_view_new();
CountDownTimView* countdown_timer_view_new();
// delete helloworld view
void countdown_timer_view_delete(CountDownTimView* hwv);
void countdown_timer_view_delete(CountDownTimView* cdv);
// return view
View* countdown_timer_view_get_view(CountDownTimView* hwv);
View* countdown_timer_view_get_view(CountDownTimView* cdv);
void countdown_timer_view_state_reset(CountDownTimView* hwv); // set initial state
void countdown_timer_state_toggle(CountDownTimView* hwv);
void countdown_timer_view_state_reset(CountDownTimView* cdv); // set initial state
void countdown_timer_state_toggle(CountDownTimView* cdv);
#endif // __COUNTDOWN_VIEW_H__