From f2d591ce164086cdb0e57a49e867058e59457795 Mon Sep 17 00:00:00 2001
From: ConfuSomu
Date: Mon, 15 Feb 2021 11:06:57 -0500
Subject: Implement home menu

Buttons are now detected and reported to the current running application
(demoed in main_clock and home_menu with `oledWriteString(oled, 0,0,2,
&data[0], FONT_6x8, 0, 1);`). I start to see the limitations with
APP_DATA. It will be dropped in a futur commit after moving each app
into its own namespace. Variables will be allocated dynamically on app
init.
---
 apps/home_menu.c  | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 apps/home_menu.h  | 15 ++++++++++
 apps/main_clock.c |  6 +++-
 apps/main_clock.h |  2 +-
 4 files changed, 109 insertions(+), 2 deletions(-)
 create mode 100644 apps/home_menu.c
 create mode 100644 apps/home_menu.h

(limited to 'apps')

diff --git a/apps/home_menu.c b/apps/home_menu.c
new file mode 100644
index 0000000..b7c15b0
--- /dev/null
+++ b/apps/home_menu.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include "pico/stdlib.h"
+#include "hardware/rtc.h"
+#include "pico/util/datetime.h"
+#include "../oled/ss_oled.h"
+
+#include "home_menu.h"
+#include "../buttons.h"
+
+extern void app_switch(int old_appid, int new_appid);
+
+#define NUMBER_OF_APPS 2
+
+char* APPS_NAME[NUMBER_OF_APPS][12] = {"Home", "Clock"};
+
+void title_str(char *buf, uint buf_size, const datetime_t *t) {
+    snprintf(buf,
+             buf_size,
+             "%d:%02d Home Menu",
+             t->hour,
+             t->min,
+             t->sec);
+};
+
+void show_title(SSOLED *oled) {
+    char datetime_buf[256];
+    char *datetime_str = &datetime_buf[0];
+    datetime_t t;
+    rtc_get_datetime(&t);
+
+    // title with time
+    title_str(datetime_str, sizeof(datetime_buf), &t);
+    oledWriteString(oled, 0,0,0, datetime_str, FONT_8x8, 0, 1);
+}
+
+// Rendering of app
+int home_menu_render(SSOLED *oled, char *data, uint data_size) {
+    show_title(oled);
+    oledWriteString(oled, 0,0,2, &data[0], FONT_6x8, 0, 1);
+    oledWriteString(oled, 0,5,3, APPS_NAME[data[1]][0], FONT_12x16, 0, 1); // FIXME: The name does not update, it seems that the second string is empty… but data[1]'s content is correct, as BUTTON_SELECT switches to the correct app.
+    return 0;
+}
+
+// Interpret button inputs
+int home_menu_btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio) {
+    switch (gpio) {
+        case BUTTON_HOME:
+            data[0] = 'H'; break;
+        case BUTTON_SELECT:
+            data[0] = 'S';
+            app_switch(0, data[1]);
+            break;
+        case BUTTON_MODE:
+            data[0] = 'M'; break;
+        case BUTTON_DOWN:
+            data[0] = 'D';
+            data[1]--;
+            break;
+        case BUTTON_UP:
+            data[0] = 'U';
+            data[1]++;
+            break;
+        default:
+            data[0] = '?';
+    }
+    if (data[1] > NUMBER_OF_APPS-1) {
+        data[1] = NUMBER_OF_APPS-1; data[0] = '>';
+    } else if (data[1] < NUMBER_OF_APPS-1) {
+        data[1] = 0; data[0] = '<';
+    }
+    return 0;
+}
+
+// Initlisation of the app.
+int home_menu_init(SSOLED *oled, char *data, uint data_size) {
+    data[1] = 0;
+    return 0; // return 1 when function not implemented
+}
+
+// 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 home_menu_bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground) {
+    return 1;
+}
+
+// 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 home_menu_destroy(SSOLED *oled, char *data, uint data_size) {
+    return 1;
+}
diff --git a/apps/home_menu.h b/apps/home_menu.h
new file mode 100644
index 0000000..507e818
--- /dev/null
+++ b/apps/home_menu.h
@@ -0,0 +1,15 @@
+#ifndef __HOME_MENU_H__
+#define __HOME_MENU_H__
+
+#include "pico/util/datetime.h"
+#include "../oled/ss_oled.h"
+
+void show_title(SSOLED *oled);
+
+int home_menu_init(SSOLED *oled, char *data, uint data_size);
+int home_menu_render(SSOLED *oled, char *data, uint data_size);
+int home_menu_btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio);
+int home_menu_bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground);
+int home_menu_destroy(SSOLED *oled, char *data, uint data_size);
+
+#endif
\ No newline at end of file
diff --git a/apps/main_clock.c b/apps/main_clock.c
index 496c696..547057e 100644
--- a/apps/main_clock.c
+++ b/apps/main_clock.c
@@ -51,6 +51,7 @@ void show_datetime(SSOLED *oled) {
     oledWriteString(oled, 0,0,7, datetime_str, FONT_8x8, 0, 1);
 }
 
+// Rendering of the app
 int main_clock_render(SSOLED *oled, char *data, uint data_size) {
     oledWriteString(oled, 0,15,0, (char *)"Test clock", FONT_8x8, 0, 1);
     show_datetime(oled);
@@ -78,14 +79,17 @@ int main_clock_btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio) {
     return 0;
 }
 
+// Initlisation of the app.
 int main_clock_init(SSOLED *oled, char *data, uint data_size) {
     return 1; // return 1 when function not implemented
 }
 
-int main_clock_bgrefresh(SSOLED *oled, char *data, uint data_size) {
+// 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 main_clock_bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground) {
     return 1;
 }
 
+// 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 main_clock_destroy(SSOLED *oled, char *data, uint data_size) {
     return 1;
 }
diff --git a/apps/main_clock.h b/apps/main_clock.h
index a7acdfe..70d9755 100644
--- a/apps/main_clock.h
+++ b/apps/main_clock.h
@@ -11,7 +11,7 @@ void show_datetime(SSOLED *oled);
 int main_clock_init(SSOLED *oled, char *data, uint data_size);
 int main_clock_render(SSOLED *oled, char *data, uint data_size);
 int main_clock_btnpressed(SSOLED *oled, char *data, uint data_size, uint gpio);
-int main_clock_bgrefresh(SSOLED *oled, char *data, uint data_size);
+int main_clock_bgrefresh(SSOLED *oled, char *data, uint data_size, char in_foreground);
 int main_clock_destroy(SSOLED *oled, char *data, uint data_size);
 
 #endif
\ No newline at end of file
-- 
cgit v1.2.3-54-g00ecf