1
0
Fork 0

Refactor ScreenList to make it more generic : it can now contain any Screen type.

Integrate this new ScreenList in SystemInfo.

Add ApplicationList, which is a ScreenList of Tile. This allows to display a menu of more than 6 applications.
This commit is contained in:
JF 2020-08-14 09:46:37 +02:00
parent 27fa273d83
commit f5328ec9eb
15 changed files with 380 additions and 208 deletions

View file

@ -333,10 +333,11 @@ list(APPEND SOURCE_FILES
DisplayApp/Screens/BatteryIcon.cpp DisplayApp/Screens/BatteryIcon.cpp
DisplayApp/Screens/BleIcon.cpp DisplayApp/Screens/BleIcon.cpp
DisplayApp/Screens/Brightness.cpp DisplayApp/Screens/Brightness.cpp
DisplayApp/Screens/ScreenList.cpp DisplayApp/Screens/SystemInfo.cpp
DisplayApp/Screens/Label.cpp DisplayApp/Screens/Label.cpp
DisplayApp/Screens/FirmwareUpdate.cpp DisplayApp/Screens/FirmwareUpdate.cpp
DisplayApp/Screens/Music.cpp DisplayApp/Screens/Music.cpp
DisplayApp/Screens/ApplicationList.cpp
main.cpp main.cpp
drivers/St7789.cpp drivers/St7789.cpp
drivers/SpiNorFlash.cpp drivers/SpiNorFlash.cpp
@ -412,9 +413,12 @@ set(INCLUDE_FILES
DisplayApp/Screens/BatteryIcon.h DisplayApp/Screens/BatteryIcon.h
DisplayApp/Screens/BleIcon.cpp DisplayApp/Screens/BleIcon.cpp
DisplayApp/Screens/Brightness.h DisplayApp/Screens/Brightness.h
DisplayApp/Screens/SystemInfo.h
DisplayApp/Screens/ScreenList.h DisplayApp/Screens/ScreenList.h
DisplayApp/Screens/Label.h DisplayApp/Screens/Label.h
DisplayApp/Screens/FirmwareUpdate.h DisplayApp/Screens/FirmwareUpdate.h
DisplayApp/Screens/ApplicationList.h
DisplayApp/Apps.h
drivers/St7789.h drivers/St7789.h
drivers/SpiNorFlash.h drivers/SpiNorFlash.h
drivers/SpiMaster.h drivers/SpiMaster.h

7
src/DisplayApp/Apps.h Normal file
View file

@ -0,0 +1,7 @@
#pragma once
namespace Pinetime {
namespace Applications {
enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness, Music};
}
}

View file

@ -2,22 +2,20 @@
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <task.h> #include <task.h>
#include <libraries/log/nrf_log.h> #include <libraries/log/nrf_log.h>
#include <boards.h>
#include <nrf_font.h> #include <nrf_font.h>
#include <queue.h> #include <queue.h>
#include <Components/DateTime/DateTimeController.h> #include <Components/DateTime/DateTimeController.h>
#include <drivers/Cst816s.h> #include <drivers/Cst816s.h>
#include <string> #include <string>
#include <lvgl/lvgl.h>
#include <DisplayApp/Screens/Tile.h> #include <DisplayApp/Screens/Tile.h>
#include <DisplayApp/Screens/Message.h>
#include <DisplayApp/Screens/Meter.h> #include <DisplayApp/Screens/Meter.h>
#include <DisplayApp/Screens/Gauge.h> #include <DisplayApp/Screens/Gauge.h>
#include <DisplayApp/Screens/Brightness.h> #include <DisplayApp/Screens/Brightness.h>
#include <DisplayApp/Screens/ScreenList.h> #include <DisplayApp/Screens/SystemInfo.h>
#include <DisplayApp/Screens/Music.h> #include <DisplayApp/Screens/Music.h>
#include <Components/Ble/NotificationManager.h> #include <Components/Ble/NotificationManager.h>
#include <DisplayApp/Screens/FirmwareUpdate.h> #include <DisplayApp/Screens/FirmwareUpdate.h>
#include <DisplayApp/Screens/ApplicationList.h>
#include "../SystemTask/SystemTask.h" #include "../SystemTask/SystemTask.h"
using namespace Pinetime::Applications; using namespace Pinetime::Applications;
@ -180,13 +178,13 @@ void DisplayApp::RunningState() {
onClockApp = false; onClockApp = false;
switch(nextApp) { switch(nextApp) {
case Apps::None: case Apps::None:
case Apps::Launcher: currentScreen.reset(new Screens::Tile(this)); break; case Apps::Launcher: currentScreen.reset(new Screens::ApplicationList(this)); break;
case Apps::Clock: case Apps::Clock:
currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController));
onClockApp = true; onClockApp = true;
break; break;
// case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; // case Apps::Test: currentScreen.reset(new Screens::Message(this)); break;
case Apps::SysInfo: currentScreen.reset(new Screens::ScreenList(this, dateTimeController, batteryController, brightnessController, bleController, watchdog)); break; case Apps::SysInfo: currentScreen.reset(new Screens::SystemInfo(this, dateTimeController, batteryController, brightnessController, bleController, watchdog)); break;
case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break; case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break; case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break;
case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break; case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break;
@ -238,7 +236,7 @@ TouchEvents DisplayApp::OnTouchEvent() {
return TouchEvents::None; return TouchEvents::None;
} }
void DisplayApp::StartApp(DisplayApp::Apps app) { void DisplayApp::StartApp(Apps app) {
nextApp = app; nextApp = app;
} }

View file

@ -18,6 +18,7 @@
#include <DisplayApp/Screens/Modal.h> #include <DisplayApp/Screens/Modal.h>
#include <Components/Ble/NotificationManager.h> #include <Components/Ble/NotificationManager.h>
#include "TouchEvents.h" #include "TouchEvents.h"
#include "Apps.h"
namespace Pinetime { namespace Pinetime {
@ -42,7 +43,6 @@ namespace Pinetime {
void Start(); void Start();
void PushMessage(Messages msg); void PushMessage(Messages msg);
enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness, Music};
void StartApp(Apps app); void StartApp(Apps app);
void SetFullRefresh(FullRefreshDirections direction); void SetFullRefresh(FullRefreshDirections direction);

View file

@ -10,7 +10,7 @@
* Bpp : 1 bit-per-pixel * Bpp : 1 bit-per-pixel
* Do not enable font compression and horizontal subpixel hinting * Do not enable font compression and horizontal subpixel hinting
* Load the file `JetBrainsMono-Bold.woff` and specify the following range : `0x20-0x7f` * Load the file `JetBrainsMono-Bold.woff` and specify the following range : `0x20-0x7f`
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185` * Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069`
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts` * Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
Add new symbols: Add new symbols:

View file

@ -433,6 +433,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
/* U+7E "~" */ /* U+7E "~" */
0x78, 0xff, 0x3c, 0xff, 0x1e, 0x78, 0xff, 0x3c, 0xff, 0x1e,
/* U+F001 "" */
0x0, 0x0, 0x70, 0x0, 0x7f, 0x0, 0x3f, 0xf0,
0x1f, 0xff, 0x7, 0xff, 0xf0, 0x7f, 0xff, 0x7,
0xfc, 0x70, 0x7e, 0x7, 0x7, 0x0, 0x70, 0x70,
0x7, 0x7, 0x0, 0x70, 0x70, 0x7, 0x7, 0x0,
0x70, 0x70, 0x7f, 0x7, 0xf, 0xf7, 0xf0, 0xff,
0xff, 0x7, 0xef, 0xf0, 0x0, 0xff, 0x0, 0x3,
0xc0, 0x0,
/* U+F017 "" */ /* U+F017 "" */
0x3, 0xf8, 0x1, 0xff, 0xc0, 0x7f, 0xfc, 0x1f, 0x3, 0xf8, 0x1, 0xff, 0xc0, 0x7f, 0xfc, 0x1f,
0xff, 0xc7, 0xf1, 0xfc, 0xfe, 0x3f, 0x9f, 0xc7, 0xff, 0xc7, 0xf1, 0xfc, 0xfe, 0x3f, 0x9f, 0xc7,
@ -449,6 +458,14 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0xf, 0x0, 0x0, 0xf3, 0xff, 0xff, 0x3f, 0xff, 0xf, 0x0, 0x0, 0xf3, 0xff, 0xff, 0x3f, 0xff,
0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0,
/* U+F069 "" */
0x0, 0xe0, 0x0, 0x1c, 0x0, 0x3, 0x80, 0x0,
0x70, 0x6, 0xe, 0xc, 0xf1, 0xc7, 0x9f, 0xbb,
0xf1, 0xff, 0xfc, 0xf, 0xfe, 0x0, 0x7f, 0x0,
0xf, 0xe0, 0x7, 0xff, 0x3, 0xff, 0xf8, 0xfd,
0xdf, 0x9e, 0x38, 0xf3, 0x7, 0x6, 0x0, 0xe0,
0x0, 0x1c, 0x0, 0x3, 0x80, 0x0, 0x70, 0x0,
/* U+F129 "" */ /* U+F129 "" */
0x3c, 0x7e, 0x7e, 0x7e, 0x3c, 0x0, 0x0, 0xfc, 0x3c, 0x7e, 0x7e, 0x7e, 0x3c, 0x0, 0x0, 0xfc,
0xfc, 0xfc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0xfc, 0xfc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
@ -526,6 +543,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0x81, 0xf8, 0x6d, 0x99, 0x9a, 0x36, 0x7, 0x80, 0x81, 0xf8, 0x6d, 0x99, 0x9a, 0x36, 0x7, 0x80,
0xe0, 0x18, 0x2, 0x0, 0x0, 0xe0, 0x18, 0x2, 0x0, 0x0,
/* U+F3FD "" */
0x0, 0xfe, 0x0, 0x7, 0xff, 0x0, 0x3f, 0xbf,
0x80, 0xfe, 0x2f, 0x83, 0xfe, 0xcf, 0x8f, 0x3f,
0x27, 0x9e, 0x7e, 0x4f, 0x3f, 0xfc, 0xfe, 0xff,
0xf3, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xcf, 0xff,
0xfe, 0x3f, 0xfe, 0x78, 0x3c, 0xff, 0xf0, 0x7f,
0xdf, 0xe0, 0xff, 0x3f, 0xff, 0xfe, 0x3f, 0xff,
0xf8,
/* U+F54B "" */ /* U+F54B "" */
0x0, 0xf, 0xf8, 0x1, 0xdf, 0xff, 0x1, 0xef, 0x0, 0xf, 0xf8, 0x1, 0xdf, 0xff, 0x1, 0xef,
0xff, 0xc0, 0xf7, 0xff, 0xf0, 0x7b, 0xff, 0xf8, 0xff, 0xc0, 0xf7, 0xff, 0xf0, 0x7b, 0xff, 0xf8,
@ -534,7 +560,16 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
0x0, 0x0, 0x0, 0x7, 0xf8, 0x0, 0xf, 0xfe, 0x0, 0x0, 0x0, 0x7, 0xf8, 0x0, 0xf, 0xfe,
0x3, 0xbf, 0xff, 0x83, 0xdf, 0xff, 0xc1, 0xef, 0x3, 0xbf, 0xff, 0x83, 0xdf, 0xff, 0xc1, 0xef,
0xff, 0xe0, 0xf7, 0xff, 0xe0, 0x3b, 0xff, 0xe0, 0xff, 0xe0, 0xf7, 0xff, 0xe0, 0x3b, 0xff, 0xe0,
0x0, 0x7f, 0xc0, 0x0 0x0, 0x7f, 0xc0, 0x0,
/* U+F560 "" */
0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0xf, 0x0,
0x1, 0xf0, 0x8, 0x3e, 0x1, 0xc7, 0xc4, 0x1e,
0xf8, 0xe1, 0xff, 0x1f, 0xf, 0xe3, 0xf0, 0x7c,
0x7e, 0x23, 0x8f, 0xc7, 0x11, 0xf8, 0xf8, 0x3f,
0xf, 0xc7, 0xe0, 0x7e, 0xfc, 0x3, 0xff, 0x80,
0x1f, 0xf0, 0x0, 0xfe, 0x0, 0x7, 0xc0, 0x0,
0x38, 0x0, 0x1, 0x0, 0x0
}; };
@ -639,20 +674,24 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 1423, .adv_w = 192, .box_w = 3, .box_h = 18, .ofs_x = 5, .ofs_y = -2}, {.bitmap_index = 1423, .adv_w = 192, .box_w = 3, .box_h = 18, .ofs_x = 5, .ofs_y = -2},
{.bitmap_index = 1430, .adv_w = 192, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -2}, {.bitmap_index = 1430, .adv_w = 192, .box_w = 10, .box_h = 18, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1453, .adv_w = 192, .box_w = 10, .box_h = 4, .ofs_x = 1, .ofs_y = 5}, {.bitmap_index = 1453, .adv_w = 192, .box_w = 10, .box_h = 4, .ofs_x = 1, .ofs_y = 5},
{.bitmap_index = 1458, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, {.bitmap_index = 1458, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 1506, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, {.bitmap_index = 1508, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 1549, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 1556, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 1568, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3}, {.bitmap_index = 1599, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 1618, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 1647, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1654, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1}, {.bitmap_index = 1666, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 1697, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, {.bitmap_index = 1716, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1735, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, {.bitmap_index = 1752, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 1773, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, {.bitmap_index = 1795, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 1811, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, {.bitmap_index = 1833, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 1849, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1}, {.bitmap_index = 1871, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 1887, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3}, {.bitmap_index = 1909, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 1925, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3}, {.bitmap_index = 1947, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 1954, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2} {.bitmap_index = 1985, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3},
{.bitmap_index = 2023, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 2052, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 2101, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2161, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3}
}; };
/*--------------------- /*---------------------
@ -660,8 +699,9 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
*--------------------*/ *--------------------*/
static const uint16_t unicode_list_1[] = { static const uint16_t unicode_list_1[] = {
0x0, 0x23, 0x112, 0x16e, 0x1cf, 0x207, 0x229, 0x22a, 0x0, 0x16, 0x39, 0x68, 0x128, 0x184, 0x1e5, 0x21d,
0x22b, 0x22c, 0x22d, 0x27c, 0x27d, 0x534 0x23f, 0x240, 0x241, 0x242, 0x243, 0x292, 0x293, 0x3fc,
0x54a, 0x55f
}; };
/*Collect the unicode lists and glyph_id offsets*/ /*Collect the unicode lists and glyph_id offsets*/
@ -672,8 +712,8 @@ static const lv_font_fmt_txt_cmap_t cmaps[] =
.unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY
}, },
{ {
.range_start = 61463, .range_length = 1333, .glyph_id_start = 96, .range_start = 61441, .range_length = 1376, .glyph_id_start = 96,
.unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 14, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 18, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
} }
}; };

View file

@ -0,0 +1,80 @@
#include <libs/lvgl/lvgl.h>
#include <DisplayApp/DisplayApp.h>
#include <functional>
#include "ApplicationList.h"
#include "Tile.h"
#include "Symbols.h"
using namespace Pinetime::Applications::Screens;
ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp *app) :
Screen(app),
screens{app, {
[this]() -> std::unique_ptr<Screen> { return CreateScreen1(); },
//[this]() -> std::unique_ptr<Screen> { return CreateScreen2(); },
//[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); }
}
} {}
ApplicationList::~ApplicationList() {
lv_obj_clean(lv_scr_act());
}
bool ApplicationList::Refresh() {
if(running)
running = screens.Refresh();
return running;
}
bool ApplicationList::OnButtonPushed() {
running = false;
app->StartApp(Apps::Clock);
return true;
}
bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
return screens.OnTouchEvent(event);
}
std::unique_ptr<Screen> ApplicationList::CreateScreen1() {
std::array<Screens::Tile::Applications, 6> applications {
{{Symbols::asterisk, Apps::Meter},
{Symbols::tachometer, Apps::Gauge},
{Symbols::clock, Apps::Clock},
{Symbols::music, Apps::Music},
{Symbols::list, Apps::SysInfo},
{Symbols::sun, Apps::Brightness}
}
};
return std::unique_ptr<Screen>(new Screens::Tile(app, applications));
}
std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
std::array<Screens::Tile::Applications, 6> applications {
{{"0", Apps::Meter},
{"1", Apps::Gauge},
{"2", Apps::Clock},
{"3", Apps::Music},
{"4", Apps::SysInfo},
{"5", Apps::Brightness}
}
};
return std::unique_ptr<Screen>(new Screens::Tile(app, applications));
}
std::unique_ptr<Screen> ApplicationList::CreateScreen3() {
std::array<Screens::Tile::Applications, 6> applications {
{{"A", Apps::Meter},
{"B", Apps::Gauge},
{"C", Apps::Clock},
{"D", Apps::Music},
{"E", Apps::SysInfo},
{"F", Apps::Brightness}
}
};
return std::unique_ptr<Screen>(new Screens::Tile(app, applications));
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <vector>
#include <Components/Ble/NimbleController.h>
#include "Screen.h"
#include "Label.h"
#include "ScreenList.h"
#include "Gauge.h"
#include "Meter.h"
#include <functional>
namespace Pinetime {
namespace Applications {
namespace Screens {
class ApplicationList : public Screen {
public:
explicit ApplicationList(DisplayApp* app);
~ApplicationList() override;
bool Refresh() override;
bool OnButtonPushed() override;
bool OnTouchEvent(TouchEvents event) override;
private:
bool running = true;
ScreenList<1> screens;
std::unique_ptr<Screen> CreateScreen1();
std::unique_ptr<Screen> CreateScreen2();
std::unique_ptr<Screen> CreateScreen3();
};
}
}
}

View file

@ -2,6 +2,7 @@
#include <vector> #include <vector>
#include "Screen.h" #include "Screen.h"
#include <lvgl/lvgl.h>
namespace Pinetime { namespace Pinetime {
namespace Applications { namespace Applications {
@ -19,6 +20,26 @@ namespace Pinetime {
lv_obj_t * label = nullptr; lv_obj_t * label = nullptr;
const char* text = nullptr; const char* text = nullptr;
}; };
class Label2 : public Screen {
public:
Label2(DisplayApp* app, const char* text) : Screen(app), text{text} {
label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_align(label, LV_LABEL_ALIGN_LEFT);
lv_obj_set_size(label, 240, 240);
lv_label_set_text(label, text);
}
~Label2() override {
lv_obj_clean(lv_scr_act());
}
bool Refresh() override {return false;}
private:
lv_obj_t * label = nullptr;
const char* text = nullptr;
};
} }
} }
} }

View file

@ -2,40 +2,64 @@
#include <vector> #include <vector>
#include <Components/Ble/NimbleController.h> #include <Components/Ble/NimbleController.h>
#include <functional>
#include "Screen.h" #include "Screen.h"
#include "Label.h" #include "Label.h"
namespace Pinetime { namespace Pinetime {
namespace Applications { namespace Applications {
namespace Screens { namespace Screens {
template <size_t N>
class ScreenList : public Screen { class ScreenList : public Screen {
public: public:
explicit ScreenList(DisplayApp* app, ScreenList(DisplayApp* app, std::array<std::function<std::unique_ptr<Screen>()>, N>&& screens)
Pinetime::Controllers::DateTime& dateTimeController, : Screen(app), screens{std::move(screens)}, current{this->screens[0]()} {
Pinetime::Controllers::Battery& batteryController,
Pinetime::Controllers::BrightnessController& brightnessController, }
Pinetime::Controllers::Ble& bleController,
Pinetime::Drivers::WatchdogView& watchdog); ~ScreenList() override {
~ScreenList() override;
bool Refresh() override; }
bool OnButtonPushed() override;
bool OnTouchEvent(TouchEvents event) override; bool Refresh() override {
running = current->Refresh();
return running;
}
bool OnButtonPushed() override {
running = false;
return true;
}
bool OnTouchEvent(TouchEvents event) override {
switch (event) {
case TouchEvents::SwipeDown:
if (screenIndex > 0) {
current.reset(nullptr);
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
screenIndex--;
current = screens[screenIndex]();
}
return true;
case TouchEvents::SwipeUp:
if (screenIndex < screens.size() - 1) {
current.reset(nullptr);
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
screenIndex++;
current = screens[screenIndex]();
}
return true;
default:
return false;
}
return false;
}
private: private:
bool running = true; bool running = true;
uint8_t screenIndex = 0; uint8_t screenIndex = 0;
std::array<std::function<std::unique_ptr<Screen>()>, N> screens;
// TODO choose another container without dynamic alloc std::unique_ptr<Screen> current;
std::vector<Screens::Label> screens;
Pinetime::Controllers::DateTime& dateTimeController;
Pinetime::Controllers::Battery& batteryController;
Pinetime::Controllers::BrightnessController& brightnessController;
Pinetime::Controllers::Ble& bleController;
Pinetime::Drivers::WatchdogView& watchdog;
char t1[200];
char t2[200];
char t3[30];
}; };
} }
} }

View file

@ -18,6 +18,10 @@ namespace Pinetime {
static constexpr char* info = "\xEF\x84\xA9"; static constexpr char* info = "\xEF\x84\xA9";
static constexpr char* list = "\xEF\x80\xBA"; static constexpr char* list = "\xEF\x80\xBA";
static constexpr char* sun = "\xEF\x86\x85"; static constexpr char* sun = "\xEF\x86\x85";
static constexpr char* check = "\xEF\x95\xA0";
static constexpr char* music = "\xEF\x80\x81";
static constexpr char* tachometer = "\xEF\x8F\xBD";
static constexpr char* asterisk = "\xEF\x81\xA9";
} }
} }
} }

View file

@ -1,29 +1,48 @@
#include <libs/lvgl/lvgl.h> #include <libs/lvgl/lvgl.h>
#include <DisplayApp/DisplayApp.h> #include <DisplayApp/DisplayApp.h>
#include "ScreenList.h" #include <functional>
#include "SystemInfo.h"
#include "../../Version.h" #include "../../Version.h"
#include "Tile.h"
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
// TODO this class must be improved to receive the list of "sub screens" via pointer or SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp *app,
// move operation. Pinetime::Controllers::DateTime &dateTimeController,
// It should accept many type of "sub screen" (it only supports Label for now). Pinetime::Controllers::Battery& batteryController,
// The number of sub screen it supports must be dynamic. Pinetime::Controllers::BrightnessController& brightnessController,
ScreenList::ScreenList(Pinetime::Applications::DisplayApp *app,
Pinetime::Controllers::DateTime &dateTimeController,
Pinetime::Controllers::Battery& batteryController,
Pinetime::Controllers::BrightnessController& brightnessController,
Pinetime::Controllers::Ble& bleController, Pinetime::Controllers::Ble& bleController,
Pinetime::Drivers::WatchdogView& watchdog) : Pinetime::Drivers::WatchdogView& watchdog) :
Screen(app), Screen(app),
dateTimeController{dateTimeController}, batteryController{batteryController}, dateTimeController{dateTimeController}, batteryController{batteryController},
brightnessController{brightnessController}, bleController{bleController}, watchdog{watchdog} { brightnessController{brightnessController}, bleController{bleController}, watchdog{watchdog},
screens.reserve(3); screens{app, {
[this]() -> std::unique_ptr<Screen> { return CreateScreen1(); },
// TODO all of this is far too heavy (string processing). This should be improved. [this]() -> std::unique_ptr<Screen> { return CreateScreen2(); },
// TODO the info (battery, time,...) should be updated in the Refresh method. [this]() -> std::unique_ptr<Screen> { return CreateScreen3(); }
}
} {}
SystemInfo::~SystemInfo() {
lv_obj_clean(lv_scr_act());
}
bool SystemInfo::Refresh() {
screens.Refresh();
return running;
}
bool SystemInfo::OnButtonPushed() {
running = false;
return true;
}
bool SystemInfo::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
return screens.OnTouchEvent(event);
}
std::unique_ptr<Screen> SystemInfo::CreateScreen1() {
auto batteryPercent = static_cast<int16_t>(batteryController.PercentRemaining()); auto batteryPercent = static_cast<int16_t>(batteryController.PercentRemaining());
if(batteryPercent > 100) batteryPercent = 100; if(batteryPercent > 100) batteryPercent = 100;
else if(batteryPercent < 0) batteryPercent = 0; else if(batteryPercent < 0) batteryPercent = 0;
@ -34,7 +53,7 @@ ScreenList::ScreenList(Pinetime::Applications::DisplayApp *app,
case Controllers::BrightnessController::Levels::Medium: brightness = 2; break; case Controllers::BrightnessController::Levels::Medium: brightness = 2; break;
case Controllers::BrightnessController::Levels::High: brightness = 3; break; case Controllers::BrightnessController::Levels::High: brightness = 3; break;
} }
auto resetReason = [&watchdog]() { auto resetReason = [this]() {
switch (watchdog.ResetReason()) { switch (watchdog.ResetReason()) {
case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg"; case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg";
case Drivers::Watchdog::ResetReasons::HardReset: return "hardr"; case Drivers::Watchdog::ResetReasons::HardReset: return "hardr";
@ -72,68 +91,24 @@ ScreenList::ScreenList(Pinetime::Applications::DisplayApp *app,
"Battery: %d%%\n" "Battery: %d%%\n"
"Backlight: %d/3\n" "Backlight: %d/3\n"
"Last reset: %s\n", "Last reset: %s\n",
Version::Major(), Version::Minor(), Version::Patch(), Version::Major(), Version::Minor(), Version::Patch(),
__DATE__, __TIME__, __DATE__, __TIME__,
dateTimeController.Day(), dateTimeController.Month(), dateTimeController.Year(), dateTimeController.Day(), dateTimeController.Month(), dateTimeController.Year(),
dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(),
uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds, uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds,
batteryPercent, brightness, resetReason); batteryPercent, brightness, resetReason);
screens.emplace_back(t1); return std::unique_ptr<Screen>(new Screens::Label2(app, t1));
}
std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
auto& bleAddr = bleController.Address(); auto& bleAddr = bleController.Address();
sprintf(t2, "BLE MAC: \n %2x:%2x:%2x:%2x:%2x:%2x", sprintf(t2, "BLE MAC: \n %2x:%2x:%2x:%2x:%2x:%2x",
bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]);
screens.emplace_back(t2); return std::unique_ptr<Screen>(new Screens::Label2(app, t2));
}
std::unique_ptr<Screen> SystemInfo::CreateScreen3() {
strncpy(t3, "Hello from\nthe developper!", 27); strncpy(t3, "Hello from\nthe developper!", 27);
return std::unique_ptr<Screen>(new Screens::Label2(app, t3));
screens.emplace_back(t3);
auto &screen = screens[screenIndex];
screen.Show();
}
ScreenList::~ScreenList() {
lv_obj_clean(lv_scr_act());
}
bool ScreenList::Refresh() {
auto &screen = screens[screenIndex];
screen.Refresh();
return running;
}
bool ScreenList::OnButtonPushed() {
running = false;
return true;
}
bool ScreenList::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
switch (event) {
case TouchEvents::SwipeDown:
if (screenIndex > 0) {
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
auto &oldScreen = screens[screenIndex];
oldScreen.Hide();
screenIndex--;
auto &newScreen = screens[screenIndex];
newScreen.Show();
}
return true;
case TouchEvents::SwipeUp:
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
if (screenIndex < screens.size() - 1) {
auto &oldScreen = screens[screenIndex];
oldScreen.Hide();
screenIndex++;
auto &newScreen = screens[screenIndex];
newScreen.Show();
}
return true;
default:
return false;
}
return false;
} }

View file

@ -0,0 +1,47 @@
#pragma once
#include <vector>
#include <Components/Ble/NimbleController.h>
#include "Screen.h"
#include "Label.h"
#include "ScreenList.h"
#include "Gauge.h"
#include "Meter.h"
#include <functional>
namespace Pinetime {
namespace Applications {
namespace Screens {
class SystemInfo : public Screen {
public:
explicit SystemInfo(DisplayApp* app,
Pinetime::Controllers::DateTime& dateTimeController,
Pinetime::Controllers::Battery& batteryController,
Pinetime::Controllers::BrightnessController& brightnessController,
Pinetime::Controllers::Ble& bleController,
Pinetime::Drivers::WatchdogView& watchdog);
~SystemInfo() override;
bool Refresh() override;
bool OnButtonPushed() override;
bool OnTouchEvent(TouchEvents event) override;
private:
bool running = true;
Pinetime::Controllers::DateTime& dateTimeController;
Pinetime::Controllers::Battery& batteryController;
Pinetime::Controllers::BrightnessController& brightnessController;
Pinetime::Controllers::Ble& bleController;
Pinetime::Drivers::WatchdogView& watchdog;
char t1[200];
char t2[200];
char t3[30];
ScreenList<3> screens;
std::unique_ptr<Screen> CreateScreen1();
std::unique_ptr<Screen> CreateScreen2();
std::unique_ptr<Screen> CreateScreen3();
};
}
}
}

View file

@ -17,9 +17,16 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) {
screen->OnObjectEvent(obj, event, eventData); screen->OnObjectEvent(obj, event, eventData);
} }
static const char * btnm_map1[] = {Symbols::heartBeat, Symbols::shoe, Symbols::clock, "\n", Symbols::info, Symbols::list, Symbols::sun, ""}; Tile::Tile(DisplayApp* app, std::array<Applications, 6>& applications) : Screen(app) {
for(int i = 0, appIndex = 0; i < 8; i++) {
Tile::Tile(DisplayApp* app) : Screen(app) { if(i == 3) btnm_map1[i] = "\n";
else if(i == 7) btnm_map1[i] = "";
else {
btnm_map1[i] = applications[appIndex].icon;
apps[appIndex] = applications[appIndex].application;
appIndex++;
}
}
modal.reset(new Modal(app)); modal.reset(new Modal(app));
btnm1 = lv_btnm_create(lv_scr_act(), NULL); btnm1 = lv_btnm_create(lv_scr_act(), NULL);
@ -41,61 +48,15 @@ bool Tile::Refresh() {
void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) {
auto* tile = static_cast<Tile*>(obj->user_data); auto* tile = static_cast<Tile*>(obj->user_data);
if(event == LV_EVENT_VALUE_CHANGED) { if(event == LV_EVENT_VALUE_CHANGED) {
switch(buttonId) { app->StartApp(apps[buttonId]);
case 0: running = false;
tile->StartMeterApp();
break;
case 1:
tile->StartGaugeApp();
break;
case 2:
tile->StartClockApp();
break;
case 3:
char versionStr[20];
sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch());
modal->Show(versionStr);
break;
case 4:
tile->StartSysInfoApp();
break;
case 5:
tile->StartBrightnessApp();
break;
}
clickCount++;
} }
} }
bool Tile::OnButtonPushed() { bool Tile::OnButtonPushed() {
app->StartApp(DisplayApp::Apps::Clock); app->StartApp(Apps::Clock);
running = false; running = false;
return true; return true;
} }
void Tile::StartClockApp() {
app->StartApp(DisplayApp::Apps::Clock);
running = false;
}
void Tile::StartSysInfoApp() {
app->StartApp(DisplayApp::Apps::SysInfo);
running = false;
}
void Tile::StartBrightnessApp() {
app->StartApp(DisplayApp::Apps::Brightness);
running = false;
}
void Tile::StartMeterApp() {
app->StartApp(DisplayApp::Apps::Meter);
running = false;
}
void Tile::StartGaugeApp() {
app->StartApp(DisplayApp::Apps::Music);
running = false;
}

View file

@ -5,13 +5,19 @@
#include <bits/unique_ptr.h> #include <bits/unique_ptr.h>
#include "Modal.h" #include "Modal.h"
#include <lvgl/src/lv_core/lv_style.h> #include <lvgl/src/lv_core/lv_style.h>
#include <DisplayApp/Apps.h>
namespace Pinetime { namespace Pinetime {
namespace Applications { namespace Applications {
namespace Screens { namespace Screens {
class Tile : public Screen { class Tile : public Screen {
public: public:
explicit Tile(DisplayApp* app); struct Applications {
const char* icon;
Pinetime::Applications::Apps application;
};
explicit Tile(DisplayApp* app, std::array<Applications, 6>& applications);
~Tile() override; ~Tile() override;
bool Refresh() override; bool Refresh() override;
@ -20,40 +26,13 @@ namespace Pinetime {
void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId);
private: private:
lv_style_t* labelRelStyle;
lv_style_t* labelPrStyle;
lv_obj_t * label1;
lv_obj_t * label2;
lv_obj_t * label3;
lv_obj_t* backgroundLabel;
lv_obj_t * button;
lv_obj_t * labelClick;
lv_obj_t *tileview;
lv_obj_t * tile1;
lv_obj_t * tile2;
lv_obj_t * list;
lv_obj_t * list_btn;
lv_obj_t * tile3;
lv_obj_t * btn1;
lv_obj_t * btn2;
lv_obj_t * btn3;
lv_obj_t * btnm1; lv_obj_t * btnm1;
lv_obj_t * btnm2;
uint32_t clickCount = 0 ;
uint32_t previousClickCount = 0;
void StartClockApp();
void StartSysInfoApp();
void StartMeterApp();
void StartGaugeApp();
bool running = true; bool running = true;
std::unique_ptr<Modal> modal; std::unique_ptr<Modal> modal;
void StartBrightnessApp();
const char* btnm_map1[8];
Pinetime::Applications::Apps apps[6];
}; };
} }
} }