diff options
-rw-r--r-- | app_manager.cpp | 1 | ||||
-rw-r--r-- | apps/settings/main.cpp | 333 | ||||
-rw-r--r-- | apps/settings/main.hpp | 36 | ||||
-rw-r--r-- | apps/settings/strings-undef.hpp | 18 | ||||
-rw-r--r-- | apps/settings/strings.hpp | 21 |
5 files changed, 215 insertions, 194 deletions
diff --git a/app_manager.cpp b/app_manager.cpp index e903ff6..c5f6d6b 100644 --- a/app_manager.cpp +++ b/app_manager.cpp @@ -29,6 +29,7 @@ BaseApp* app_create(int app_id) { switch (app_id) { case 0: open_apps.push_back(new app_home_menu(&app_api)); break; case 1: open_apps.push_back(new app_main_clock(&app_api)); break; + case 2: open_apps.push_back(new app_settings(&app_api)); break; default: __breakpoint(); return open_apps.front(); // Should be home_menu } // TODO: Check when new fails diff --git a/apps/settings/main.cpp b/apps/settings/main.cpp index 26c8e25..555c2c1 100644 --- a/apps/settings/main.cpp +++ b/apps/settings/main.cpp @@ -2,212 +2,175 @@ #include "pico/stdlib.h" #include "main.hpp" -#include "../../api.hpp" #include "../../globals.hpp" +#include "strings.hpp" -extern void app_switch(int old_appid, int new_appid); extern bool rtc_get_datetime(datetime_t *t); -#define MAIN_SET_NUM 2 -#define MAIN_SET_NUM_STR "2" -#define SIZE_SETTING_NAME 12 -#define STR_SET_APPLY "Apply and close" -#define STR_SET_CANCEL "Quit without saving" -#define SET0_NAME "Date & Time" -#define SET1_NAME "Display" - -#define SET0_DESC "Set date/time. Choose unit to change:" -#define SET0_0_DESC "Adjust selected unit. Use good values!" -#define SET0_1_DESC "Set the current month or day of week." - -#define SET1_DESC "Adjust settings related to OLED display." -#define SET1_0_DESC "Adjust display brightness." -#define SET1_1_DESC "Time before turning off OLED and entering low power." -#define SET1_2_DESC "Set display time format.\nCurrent:\nY: 24h\nN: AM/PM" -#define SET1_2_DESC_INDEX_CURRENT 33 // Don't forget me! -#define SET1_1_MIN 5000 -// According to https://stackoverflow.com/questions/589575/what-does-the-c-standard-state-the-size-of-int-long-type-to-be : -#define SET1_1_MAX 65500 -#define SET1_1_STEP 500 - -namespace app_settings { - const char *MAIN_SET_NAMES[MAIN_SET_NUM] = {SET0_NAME, SET1_NAME}; - int selected_setting = 0; - char display_setting_name[SIZE_SETTING_NAME]; - bool selected = false; - - void show_title(Api *app_api) { - std::string title_str {"Settings (/" MAIN_SET_NUM_STR ")"}; - title_str.insert(10, std::to_string(selected_setting+1)); - app_api->gui_header_text(title_str); - } +void app_settings::show_title(Api *app_api) { + std::string title_str {"Settings (/" MAIN_SET_NUM_STR ")"}; + title_str.insert(10, std::to_string(selected_setting+1)); + app_api->gui_header_text(title_str); +} - // Time and date settings - void set0_menu(Api *app_api) { - #define NUM_CHOICES 9 - static const char *choices[NUM_CHOICES] = {"Hour", "Minute", "Second", "Year", "Month", "Day", "Day of week", STR_SET_APPLY, STR_SET_CANCEL}; - uint max_value; - uint min_value; - uint default_value; - datetime_t datetime; - app_api->datetime_get(&datetime); - - int choice = 0; - while (true) { - choice = app_api->gui_popup_strchoice(SET0_NAME, SET0_DESC, choices, NUM_CHOICES, 0, -1, choice); - - min_value = 0; - switch (choice) { - case 0: // Hour - max_value = 23; - default_value = datetime.hour; - break; - case 1: // Minute - max_value = 59; - default_value = datetime.min; - break; - case 2: // Second - max_value = 59; - default_value = datetime.sec; - break; - case 3: // Year - max_value = 4095; - default_value = datetime.year; - break; - case 5: // Day - max_value = 31; // FIXME: Depends on month! - min_value = 1; - default_value = datetime.day; - break; - case 7: // Apply and exit - app_api->datetime_set(&datetime); - case 8: // Quit without saving - return; - } - - // Display popup for editing value - int new_value; - if (choice == 4) { // Month - // From newlib (which already includes this array of char arrays in the complied program). This should not take more space. - // See newlib/libc/locale/timelocal.c (mirror @ https://github.com/bminor/newlib/blob/80cda9bbda04a1e9e3bee5eadf99061ed69ca5fb/newlib/libc/locale/timelocal.c#L40) - static const char *month_choice[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; - - datetime.month = app_api->gui_popup_strchoice(choices[choice], SET0_1_DESC, month_choice, 12, 0, -1, datetime.month - 1) + 1; - - } else if (choice == 6) { // Day of week - static const char *dotw_choice[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; - - datetime.dotw = app_api->gui_popup_strchoice(choices[choice], SET0_1_DESC, dotw_choice, 7, 0, -1, datetime.dotw); - - } else { - new_value = app_api->gui_popup_intchoice(choices[choice], SET0_0_DESC, min_value, max_value, default_value); - } - - // Store the modification in the struct - switch (choice) { - case 0: datetime.hour = new_value; break; - case 1: datetime.min = new_value; break; - case 2: datetime.sec = new_value; break; - case 3: datetime.year = new_value; break; - // Month & date of week is stored directly after their special popup. - case 5: datetime.day = new_value; break; - } +// Time and date settings +void app_settings::set0_menu(Api *app_api) { + #define NUM_CHOICES 9 + static const char *choices[NUM_CHOICES] = {"Hour", "Minute", "Second", "Year", "Month", "Day", "Day of week", STR_SET_APPLY, STR_SET_CANCEL}; + uint max_value; + uint min_value; + uint default_value; + datetime_t datetime; + app_api->datetime_get(&datetime); + + int choice = 0; + while (true) { + choice = app_api->gui_popup_strchoice(SET0_NAME, SET0_DESC, choices, NUM_CHOICES, 0, -1, choice); + + min_value = 0; + switch (choice) { + case 0: // Hour + max_value = 23; + default_value = datetime.hour; + break; + case 1: // Minute + max_value = 59; + default_value = datetime.min; + break; + case 2: // Second + max_value = 59; + default_value = datetime.sec; + break; + case 3: // Year + max_value = 4095; + default_value = datetime.year; + break; + case 5: // Day + max_value = 31; // FIXME: Depends on month! + min_value = 1; + default_value = datetime.day; + break; + case 7: // Apply and exit + app_api->datetime_set(&datetime); + case 8: // Quit without saving + return; } - #undef NUM_CHOICES - } - // Display settings - void set1_menu(Api *app_api) { - #define NUM_CHOICES 4 - static const char *choices[NUM_CHOICES] = {"Display brightness", "Sleep timeout", "Time format", STR_SET_APPLY}; - - // There is no space for the "AM/PM" as this would push the last "M" on a new line, to make it nicer, a space could be afforded before the "24h" text. - static const char *time_format[2] = {"AM/PM", " 24h"}; - - int choice = 0; - while (true) { - choice = app_api->gui_popup_strchoice(SET1_NAME, SET1_DESC, choices, NUM_CHOICES, 0,-1,choice); - - switch(choice) { - case 0: // Display brightness - g_user.oled_contrast = app_api->gui_popup_intchoice(SET1_NAME, SET1_0_DESC, 1, 255, g_user.oled_contrast, 5); - app_api->display_set_contrast(g_user.oled_contrast); - break; - case 1: // Sleep timeout - g_user.sleep_delay = app_api->gui_popup_intchoice(SET1_NAME, SET1_1_DESC, SET1_1_MIN, SET1_1_MAX, g_user.sleep_delay, SET1_1_STEP); - break; - case 2: // Time format - // TODO: Rewrite this, one day - g_user.time_format = app_api->gui_popup_booleanchoice(SET1_NAME, ((std::string)SET1_2_DESC).insert(SET1_2_DESC_INDEX_CURRENT, time_format[(int)g_user.time_format])); - break; - case 3: - return; - } - } - #undef NUM_CHOICES - } + // Display popup for editing value + int new_value; + if (choice == 4) { // Month + // From newlib (which already includes this array of char arrays in the complied program). This should not take more space. + // See newlib/libc/locale/timelocal.c (mirror @ https://github.com/bminor/newlib/blob/80cda9bbda04a1e9e3bee5eadf99061ed69ca5fb/newlib/libc/locale/timelocal.c#L40) + static const char *month_choice[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; + + datetime.month = app_api->gui_popup_strchoice(choices[choice], SET0_1_DESC, month_choice, 12, 0, -1, datetime.month - 1) + 1; - // Rendering of app - int render(Api *app_api) { - show_title(app_api); - app_api->display_write_string(0,0,3, display_setting_name, FONT_12x16, 0, 1); - - if (selected) { - selected = false; - switch (selected_setting) { - case 0: - set0_menu(app_api); - break; - case 1: - set1_menu(app_api); - break; - } + } else if (choice == 6) { // Day of week + static const char *dotw_choice[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; + + datetime.dotw = app_api->gui_popup_strchoice(choices[choice], SET0_1_DESC, dotw_choice, 7, 0, -1, datetime.dotw); + + } else { + new_value = app_api->gui_popup_intchoice(choices[choice], SET0_0_DESC, min_value, max_value, default_value); } - return 0; + // Store the modification in the struct + switch (choice) { + case 0: datetime.hour = new_value; break; + case 1: datetime.min = new_value; break; + case 2: datetime.sec = new_value; break; + case 3: datetime.year = new_value; break; + // Month & date of week is stored directly after their special popup. + case 5: datetime.day = new_value; break; + } } + #undef NUM_CHOICES +} + +// Display settings +void app_settings::set1_menu(Api *app_api) { + #define NUM_CHOICES 4 + static const char *choices[NUM_CHOICES] = {"Display brightness", "Sleep timeout", "Time format", STR_SET_APPLY}; + + // There is no space for the "AM/PM" as this would push the last "M" on a new line, to make it nicer, a space could be afforded before the "24h" text. + static const char *time_format[2] = {"AM/PM", " 24h"}; + + int choice = 0; + while (true) { + choice = app_api->gui_popup_strchoice(SET1_NAME, SET1_DESC, choices, NUM_CHOICES, 0,-1,choice); - // Example of how button inputs could be interpreted. - // Drawing on screen should be done in the render function. - int btnpressed(Api *app_api, uint gpio, unsigned long delta) { - switch (gpio) { - case BUTTON_SELECT: - selected = true; + switch(choice) { + case 0: // Display brightness + g_user.oled_contrast = app_api->gui_popup_intchoice(SET1_NAME, SET1_0_DESC, 1, 255, g_user.oled_contrast, 5); + app_api->display_set_contrast(g_user.oled_contrast); break; - case BUTTON_DOWN: - selected_setting--; + case 1: // Sleep timeout + g_user.sleep_delay = app_api->gui_popup_intchoice(SET1_NAME, SET1_1_DESC, SET1_1_MIN, SET1_1_MAX, g_user.sleep_delay, SET1_1_STEP); break; - case BUTTON_UP: - selected_setting++; + case 2: // Time format + // TODO: Rewrite this, one day + g_user.time_format = app_api->gui_popup_booleanchoice(SET1_NAME, ((std::string)SET1_2_DESC).insert(SET1_2_DESC_INDEX_CURRENT, time_format[(int)g_user.time_format])); break; + case 3: + return; } - if (selected_setting > MAIN_SET_NUM-1) { - selected_setting = MAIN_SET_NUM-1; - } else if (selected_setting < 0) { - selected_setting = 0; - } - // Add spaces to avoid "ghost" characters from app names displayed before - snprintf(display_setting_name, SIZE_SETTING_NAME, "%s ", MAIN_SET_NAMES[selected_setting]); - return 0; } + #undef NUM_CHOICES +} - // Initlisation of the app. - int init(Api *app_api) { - app_api->performance_set(Api::perf_modes::LOW_POWER); - app_api->performance_render_interval_set(100); - selected_setting = 0; +// Rendering of app +int app_settings::render(Api *app_api) { + show_title(app_api); + app_api->display_write_string(0,0,3, display_setting_name, FONT_12x16, 0, 1); + + if (selected) { selected = false; - snprintf(display_setting_name, SIZE_SETTING_NAME, "%s", MAIN_SET_NAMES[0]); - return Api::app_init_return_status::OK; + switch (selected_setting) { + case 0: + set0_menu(app_api); + break; + case 1: + set1_menu(app_api); + break; + } } - // Processor intensive operations and functions related to drawing to the screen should only be done when the app is in_foreground(=1). This function is only called when the app is init. - int bgrefresh(Api *app_api, bool in_foreground) { - return 1; - } + return 0; +} - // Destruction of app, deinitlisation should be done here. This is only called if the app's APPS_DESTROY_ON_EXIT is set to 1. When it is not a "service" app. - int destroy(Api *app_api) { - return 0; +int app_settings::btnpressed(Api *app_api, uint gpio, unsigned long delta) { + switch (gpio) { + case BUTTON_SELECT: + selected = true; + break; + case BUTTON_DOWN: + selected_setting--; + break; + case BUTTON_UP: + selected_setting++; + break; } + if (selected_setting > MAIN_SET_NUM-1) { + selected_setting = MAIN_SET_NUM-1; + } else if (selected_setting < 0) { + selected_setting = 0; + } + // Add spaces to avoid "ghost" characters from app names displayed before + snprintf(display_setting_name, SIZE_SETTING_NAME, "%s ", MAIN_SET_NAMES[selected_setting]); + return 0; +} + +app_settings::app_settings(Api *app_api) { + app_api->performance_set(Api::perf_modes::LOW_POWER); + app_api->performance_render_interval_set(100); + selected_setting = 0; + selected = false; + snprintf(display_setting_name, SIZE_SETTING_NAME, "%s", MAIN_SET_NAMES[0]); +} + +int app_settings::bgrefresh(Api *app_api, bool in_foreground) { + return 1; +} + +app_settings::~app_settings() { } diff --git a/apps/settings/main.hpp b/apps/settings/main.hpp index 927caca..589be70 100644 --- a/apps/settings/main.hpp +++ b/apps/settings/main.hpp @@ -1,10 +1,28 @@ #pragma once -#include "../../api.hpp" - -namespace app_settings { - int init(Api *app_api); - int render(Api *app_api); - int btnpressed(Api *app_api, uint gpio, unsigned long delta); - int bgrefresh(Api *app_api, bool in_foreground); - int destroy(Api *app_api); -} +#include "../../base_app.hpp" +#include "strings.hpp" + +class app_settings : public BaseApp { + private: + const char *MAIN_SET_NAMES[MAIN_SET_NUM] = {SET0_NAME, SET1_NAME}; + int selected_setting = 0; + char display_setting_name[SIZE_SETTING_NAME]; + bool selected = false; + + void show_title(Api *app_api); + void set0_menu(Api *app_api); + void set1_menu(Api *app_api); + + AppAttributes app_attributes = {2, true}; + public: + const AppAttributes& app_get_attributes() { + return app_attributes; + } + + app_settings(Api *app_api); + int render(Api *app_api); + int btnpressed(Api *app_api, uint gpio, unsigned long delta); + int bgrefresh(Api *app_api, bool in_foreground); + ~app_settings(); +}; +#include "strings-undef.hpp" diff --git a/apps/settings/strings-undef.hpp b/apps/settings/strings-undef.hpp new file mode 100644 index 0000000..7b5a96e --- /dev/null +++ b/apps/settings/strings-undef.hpp @@ -0,0 +1,18 @@ +#undef MAIN_SET_NUM +#undef MAIN_SET_NUM_STR +#undef SIZE_SETTING_NAME +#undef STR_SET_APPLY +#undef STR_SET_CANCEL +#undef SET0_NAME +#undef SET1_NAME +#undef SET0_DESC +#undef SET0_0_DESC +#undef SET0_1_DESC +#undef SET1_DESC +#undef SET1_0_DESC +#undef SET1_1_DESC +#undef SET1_2_DESC +#undef SET1_2_DESC_INDEX_CURRENT +#undef SET1_1_MIN +#undef SET1_1_MAX +#undef SET1_1_STEP
\ No newline at end of file diff --git a/apps/settings/strings.hpp b/apps/settings/strings.hpp new file mode 100644 index 0000000..d1cfb51 --- /dev/null +++ b/apps/settings/strings.hpp @@ -0,0 +1,21 @@ +#define MAIN_SET_NUM 2 +#define MAIN_SET_NUM_STR "2" +#define SIZE_SETTING_NAME 12 +#define STR_SET_APPLY "Apply and close" +#define STR_SET_CANCEL "Quit without saving" +#define SET0_NAME "Date & Time" +#define SET1_NAME "Display" + +#define SET0_DESC "Set date/time. Choose unit to change:" +#define SET0_0_DESC "Adjust selected unit. Use good values!" +#define SET0_1_DESC "Set the current month or day of week." + +#define SET1_DESC "Adjust settings related to OLED display." +#define SET1_0_DESC "Adjust display brightness." +#define SET1_1_DESC "Time before turning off OLED and entering low power." +#define SET1_2_DESC "Set display time format.\nCurrent:\nY: 24h\nN: AM/PM" +#define SET1_2_DESC_INDEX_CURRENT 33 // Don't forget me! +#define SET1_1_MIN 5000 +// According to https://stackoverflow.com/questions/589575/what-does-the-c-standard-state-the-size-of-int-long-type-to-be : +#define SET1_1_MAX 65500 +#define SET1_1_STEP 500
\ No newline at end of file |