Initial InfiniSim project
This commit is contained in:
327
sim/displayapp/LittleVgl.cpp
Normal file
327
sim/displayapp/LittleVgl.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include "displayapp/lv_pinetime_theme.h"
|
||||
|
||||
//#include <FreeRTOS.h>
|
||||
//#include <task.h>
|
||||
////#include <projdefs.h>
|
||||
#include "drivers/Cst816s.h"
|
||||
#include "drivers/St7789.h"
|
||||
|
||||
using namespace Pinetime::Components;
|
||||
|
||||
//lv_style_t* LabelBigStyle = nullptr;
|
||||
//
|
||||
//static void disp_flush(lv_disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p) {
|
||||
// auto* lvgl = static_cast<LittleVgl*>(disp_drv->user_data);
|
||||
// lvgl->FlushDisplay(area, color_p);
|
||||
//}
|
||||
//
|
||||
bool touchpad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data) {
|
||||
auto* lvgl = static_cast<LittleVgl*>(indev_drv->user_data);
|
||||
return lvgl->GetTouchPadInfo(data);
|
||||
}
|
||||
|
||||
LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel)
|
||||
: lcd {lcd}, touchPanel {touchPanel}, previousClick {0, 0} {
|
||||
|
||||
}
|
||||
|
||||
void LittleVgl::Init() {
|
||||
// lv_init();
|
||||
// InitDisplay();
|
||||
// InitTheme();
|
||||
InitTouchpad();
|
||||
}
|
||||
|
||||
//void LittleVgl::InitDisplay() {
|
||||
// lv_disp_draw_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 4); /*Initialize the display buffer*/
|
||||
// lv_disp_drv_init(&disp_drv); /*Basic initialization*/
|
||||
//
|
||||
// /*Set up the functions to access to your display*/
|
||||
//
|
||||
// /*Set the resolution of the display*/
|
||||
// disp_drv.hor_res = 240;
|
||||
// disp_drv.ver_res = 240;
|
||||
//
|
||||
// /*Used to copy the buffer's content to the display*/
|
||||
// disp_drv.flush_cb = disp_flush;
|
||||
// /*Set a display buffer*/
|
||||
// disp_drv.draw_buf = &disp_buf_2;
|
||||
// disp_drv.user_data = this;
|
||||
//
|
||||
// /*Finally register the driver*/
|
||||
// lv_disp_drv_register(&disp_drv);
|
||||
//}
|
||||
|
||||
void LittleVgl::InitTouchpad() {
|
||||
lv_indev_drv_t indev_drv;
|
||||
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = touchpad_read;
|
||||
indev_drv.user_data = this;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
void LittleVgl::SetFullRefresh(FullRefreshDirections direction) {
|
||||
if (scrollDirection == FullRefreshDirections::None) {
|
||||
scrollDirection = direction;
|
||||
if (scrollDirection == FullRefreshDirections::Down) {
|
||||
lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
} else if (scrollDirection == FullRefreshDirections::Right) {
|
||||
lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
} else if (scrollDirection == FullRefreshDirections::Left) {
|
||||
lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
} else if (scrollDirection == FullRefreshDirections::RightAnim) {
|
||||
lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
} else if (scrollDirection == FullRefreshDirections::LeftAnim) {
|
||||
lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
//void LittleVgl::DisplayDownScroll(){
|
||||
// // We are controlling the drawing process, disable lvgl timers
|
||||
// lv_timer_enable(false);
|
||||
//
|
||||
// // For each segment, draw the full width, 4 lines at a time starting from the bottom
|
||||
// // TODO: Should probably calculate this from the size of the draw buffer
|
||||
// int16_t height = 4;
|
||||
// int16_t width = 240;
|
||||
// int16_t y2 = 240;
|
||||
// int16_t y1 = 240 - height;
|
||||
//
|
||||
// lv_area_t area;
|
||||
// area.x1 = 0;
|
||||
// area.x2 = width;
|
||||
//
|
||||
// // Start from the bottom and create a 4 line high box
|
||||
// for (y1 = 240 - height; y1 >= 0; y1 -= height) {
|
||||
// y2 = y1 + height - 1;
|
||||
//
|
||||
// // If the box has reached the end of the visible line on the lcd controller...
|
||||
// if (y2 == visibleNbLines - 1) {
|
||||
// // move past the non visible lines
|
||||
// writeOffset += (totalNbLines - visibleNbLines);
|
||||
// // and wrap around to the start of address space
|
||||
// writeOffset %= totalNbLines;
|
||||
// }
|
||||
// // Set new box
|
||||
// area.y1 = y1;
|
||||
// area.y2 = y2;
|
||||
//
|
||||
// // Scroll as we draw
|
||||
// uint16_t toScroll = height;
|
||||
// if (scrollOffset >= toScroll)
|
||||
// scrollOffset -= toScroll;
|
||||
// else { // now we need to wrap the scroll address
|
||||
// toScroll -= scrollOffset;
|
||||
// scrollOffset = totalNbLines - toScroll;
|
||||
// }
|
||||
// lcd.VerticalScrollStartAddress(scrollOffset);
|
||||
//
|
||||
// lv_disp_t* disp = lv_disp_get_default();
|
||||
// // Clear invalid area list / tells lvgl that nothing on the screen needs to be updated
|
||||
// _lv_inv_area(disp, nullptr);
|
||||
// // invalidate only the segment we want to update in this portion of the animation
|
||||
// _lv_inv_area(disp, &area);
|
||||
// // cancel any current flushes in the display driver
|
||||
// // Since we've stopped timers, it will be waiting forever if there is currently a flush
|
||||
// lv_disp_flush_ready(disp->driver);
|
||||
// lv_refr_now(disp);
|
||||
// }
|
||||
// // Done! clear flags and enable timers
|
||||
// scrollDirection = FullRefreshDirections::None;
|
||||
// animating = false;
|
||||
// lv_timer_enable(true);
|
||||
//}
|
||||
//
|
||||
//void LittleVgl::DisplayHorizAnim() {
|
||||
// lv_timer_enable(false);
|
||||
//
|
||||
// int16_t height, width, x1, x2;
|
||||
// lv_area_t area;
|
||||
//
|
||||
// height = 240;
|
||||
// width = 4;
|
||||
// int16_t (*NextStep)(int16_t, int16_t){};
|
||||
// bool (*CheckEnd)(int16_t){};
|
||||
//
|
||||
// area.y1=0;
|
||||
// area.y2=height;
|
||||
//
|
||||
// if (scrollDirection == FullRefreshDirections::RightAnim) {
|
||||
// x1 = 0;
|
||||
//
|
||||
// CheckEnd = [](int16_t x) -> bool {
|
||||
// return (x < LV_HOR_RES_MAX);
|
||||
// };
|
||||
// NextStep = [](int16_t x, int16_t width) -> int16_t {
|
||||
// auto newx = x + width * 2;
|
||||
// if (newx < 240) {return newx;};
|
||||
// return (newx < 240 + width) ? (newx - 240 + width) : newx;
|
||||
// };
|
||||
//
|
||||
// } else if (scrollDirection == FullRefreshDirections::LeftAnim) {
|
||||
// x1 = 240 - width;
|
||||
//
|
||||
// CheckEnd = [](int16_t x) -> bool {
|
||||
// return (x >= 0);
|
||||
// };
|
||||
// NextStep = [](int16_t x, int16_t width) -> int16_t {
|
||||
// auto newx = x - width * 2;
|
||||
// if (newx >= 0) {return newx;}
|
||||
// return (newx >= 0 - width) ? (newx + 240 - width) : newx;
|
||||
// };
|
||||
//
|
||||
// } else {
|
||||
// // Not set for a horizontal animation!
|
||||
// lv_timer_enable(true);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for (; CheckEnd(x1); x1 = NextStep(x1, width)) {
|
||||
// x2 = x1 + width-1;
|
||||
//
|
||||
// if (area.y2 == visibleNbLines - 1) {
|
||||
// writeOffset += (totalNbLines - visibleNbLines);
|
||||
// writeOffset %= totalNbLines;
|
||||
// }
|
||||
// area.x1 = x1;
|
||||
// area.x2 = x2;
|
||||
//
|
||||
// lv_disp_t* disp = lv_disp_get_default();
|
||||
// _lv_inv_area(disp, nullptr);
|
||||
// _lv_inv_area(disp, &area);
|
||||
// lv_disp_flush_ready(disp->driver);
|
||||
// lv_refr_now(disp);
|
||||
// }
|
||||
// scrollDirection = FullRefreshDirections::None;
|
||||
// animating = false;
|
||||
// lv_timer_enable(true);
|
||||
//}
|
||||
//
|
||||
//void LittleVgl::FlushDisplayManually() {
|
||||
// switch(scrollDirection){
|
||||
// case FullRefreshDirections::Down:
|
||||
// DisplayDownScroll();
|
||||
// break;
|
||||
// case FullRefreshDirections::RightAnim:
|
||||
// case FullRefreshDirections::LeftAnim:
|
||||
// DisplayHorizAnim();
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
void LittleVgl::FlushDisplay(const lv_area_t* area, lv_color_t* color_p) {
|
||||
// uint16_t y1, y2, width, height = 0;
|
||||
//
|
||||
// ulTaskNotifyTake(pdTRUE, 200);
|
||||
// // NOtification is still needed (even if there is a mutex on SPI) because of the DataCommand pin
|
||||
// // which cannot be set/clear during a transfert.
|
||||
//
|
||||
// if (!animating && (scrollDirection == FullRefreshDirections::Down ||
|
||||
// scrollDirection == FullRefreshDirections::RightAnim ||
|
||||
// scrollDirection == FullRefreshDirections::LeftAnim)){
|
||||
// animating = true;
|
||||
// FlushDisplayManually();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if ((scrollDirection == FullRefreshDirections::Up) && (area->y1 == 0)) {
|
||||
// writeOffset = (writeOffset + visibleNbLines) % totalNbLines;
|
||||
// }
|
||||
//
|
||||
// y1 = (area->y1 + writeOffset) % totalNbLines;
|
||||
// y2 = (area->y2 + writeOffset) % totalNbLines;
|
||||
//
|
||||
// width = (area->x2 - area->x1) + 1;
|
||||
// height = (area->y2 - area->y1) + 1;
|
||||
//
|
||||
// if (scrollDirection == FullRefreshDirections::Up) {
|
||||
//
|
||||
// if (area->y1 > 0) {
|
||||
// if (area->y2 == visibleNbLines - 1) {
|
||||
// scrollOffset += (height * 2);
|
||||
// scrollDirection = FullRefreshDirections::None;
|
||||
//// lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
// } else {
|
||||
// scrollOffset += height;
|
||||
// }
|
||||
// scrollOffset = scrollOffset % totalNbLines;
|
||||
// lcd.VerticalScrollStartAddress(scrollOffset);
|
||||
// }
|
||||
// } else if (scrollDirection == FullRefreshDirections::Left or scrollDirection == FullRefreshDirections::LeftAnim) {
|
||||
// if (area->x2 == visibleNbLines - 1) {
|
||||
// scrollDirection = FullRefreshDirections::None;
|
||||
//// lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
// }
|
||||
// } else if (scrollDirection == FullRefreshDirections::Right or scrollDirection == FullRefreshDirections::RightAnim) {
|
||||
// if (area->x1 == 0) {
|
||||
// scrollDirection = FullRefreshDirections::None;
|
||||
//// lv_disp_set_rotation(lv_disp_get_default(), LV_DISP_ROT_NONE);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (y2 < y1) {
|
||||
// height = totalNbLines - y1;
|
||||
//
|
||||
// if (height > 0) {
|
||||
// lcd.DrawBuffer(area->x1, y1, width, height, reinterpret_cast<const uint8_t*>(color_p), width * height * 2);
|
||||
// ulTaskNotifyTake(pdTRUE, 100);
|
||||
// }
|
||||
//
|
||||
// uint16_t pixOffset = width * height;
|
||||
// height = y2 + 1;
|
||||
// lcd.DrawBuffer(area->x1, 0, width, height, reinterpret_cast<const uint8_t*>(color_p + pixOffset), width * height * 2);
|
||||
//
|
||||
// } else {
|
||||
// lcd.DrawBuffer(area->x1, y1, width, height, reinterpret_cast<const uint8_t*>(color_p), width * height * 2);
|
||||
// }
|
||||
//
|
||||
// // IMPORTANT!!!
|
||||
// // Inform the graphics library that you are ready with the flushing
|
||||
// lv_disp_flush_ready(&disp_drv);
|
||||
|
||||
lv_disp_t *disp = lv_disp_get_default();
|
||||
lv_disp_drv_t *disp_drv = &disp->driver;
|
||||
lv_area_t area_trimmed = *area;
|
||||
if (area->x1 < 0)
|
||||
area_trimmed.x1 = 0;
|
||||
if (area->x2 >= LV_HOR_RES)
|
||||
area_trimmed.x2 = LV_HOR_RES-1;
|
||||
if (area->y1 < 0)
|
||||
area_trimmed.y1 = 0;
|
||||
if (area->y2 >= LV_VER_RES)
|
||||
area_trimmed.y2 = LV_VER_RES-1;
|
||||
// tell flush_cb this is the last thing to flush to get the monitor refreshed
|
||||
lv_disp_get_buf(disp)->flushing_last = true;
|
||||
disp_drv->flush_cb(disp_drv, &area_trimmed, color_p);
|
||||
}
|
||||
|
||||
void LittleVgl::SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) {
|
||||
tap_x = x;
|
||||
tap_y = y;
|
||||
tapped = contact;
|
||||
}
|
||||
|
||||
bool LittleVgl::GetTouchPadInfo(lv_indev_data_t* ptr) {
|
||||
ptr->point.x = tap_x;
|
||||
ptr->point.y = tap_y;
|
||||
if (tapped) {
|
||||
ptr->state = LV_INDEV_STATE_PR;
|
||||
} else {
|
||||
ptr->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//void LittleVgl::InitTheme() {
|
||||
// if (!lv_pinetime_theme_is_inited()) {
|
||||
// lv_theme_t* th = lv_pinetime_theme_init(lv_disp_get_default(), lv_color_white(), lv_color_hex(0xC0C0C0), &jetbrains_mono_bold_20);
|
||||
// lv_disp_set_theme(lv_disp_get_default(), th);
|
||||
// }
|
||||
//}
|
64
sim/displayapp/LittleVgl.h
Normal file
64
sim/displayapp/LittleVgl.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Drivers {
|
||||
class Cst816S;
|
||||
class St7789;
|
||||
}
|
||||
|
||||
namespace Components {
|
||||
class LittleVgl {
|
||||
public:
|
||||
enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim };
|
||||
LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel);
|
||||
|
||||
LittleVgl(const LittleVgl&) = delete;
|
||||
LittleVgl& operator=(const LittleVgl&) = delete;
|
||||
LittleVgl(LittleVgl&&) = delete;
|
||||
LittleVgl& operator=(LittleVgl&&) = delete;
|
||||
|
||||
void Init();
|
||||
|
||||
void FlushDisplay(const lv_area_t* area, lv_color_t* color_p);
|
||||
bool GetTouchPadInfo(lv_indev_data_t* ptr);
|
||||
void SetFullRefresh(FullRefreshDirections direction);
|
||||
void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact);
|
||||
//
|
||||
// private:
|
||||
// void InitDisplay();
|
||||
void InitTouchpad();
|
||||
// void InitTheme();
|
||||
//
|
||||
// void FlushDisplayManually();
|
||||
// void DisplayDownScroll();
|
||||
// void DisplayHorizAnim();
|
||||
|
||||
Pinetime::Drivers::St7789& lcd;
|
||||
Pinetime::Drivers::Cst816S& touchPanel;
|
||||
|
||||
// lv_disp_draw_buf_t disp_buf_2;
|
||||
// lv_color_t buf2_1[LV_HOR_RES_MAX * 4];
|
||||
// lv_color_t buf2_2[LV_HOR_RES_MAX * 4];
|
||||
//
|
||||
lv_disp_drv_t disp_drv;
|
||||
lv_point_t previousClick;
|
||||
|
||||
bool firstTouch = true;
|
||||
static constexpr uint8_t nbWriteLines = 4;
|
||||
static constexpr uint16_t totalNbLines = 320;
|
||||
static constexpr uint16_t visibleNbLines = 240;
|
||||
static constexpr uint8_t MaxScrollOffset() {
|
||||
return LV_VER_RES_MAX - nbWriteLines;
|
||||
}
|
||||
FullRefreshDirections scrollDirection = FullRefreshDirections::None;
|
||||
uint16_t writeOffset = 0;
|
||||
uint16_t scrollOffset = 0;
|
||||
|
||||
uint16_t tap_x = 0;
|
||||
uint16_t tap_y = 0;
|
||||
bool tapped = false;
|
||||
};
|
||||
}
|
||||
}
|
131
sim/displayapp/screens/Missing.cpp
Normal file
131
sim/displayapp/screens/Missing.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "displayapp/screens/Missing.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
Missing::Missing(Pinetime::Applications::DisplayApp* app, Pinetime::Applications::Apps app_key) : Screen(app) {
|
||||
const char *screen_lbl;
|
||||
switch (app_key) {
|
||||
case Pinetime::Applications::Apps::None:
|
||||
screen_lbl = "None";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Launcher:
|
||||
screen_lbl = "Launcher";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Clock:
|
||||
screen_lbl = "Clock";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SysInfo:
|
||||
screen_lbl = "SysInfo";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::FirmwareUpdate:
|
||||
screen_lbl = "FirmwareUpdate";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::FirmwareValidation:
|
||||
screen_lbl = "FirmwareValidation";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::NotificationsPreview:
|
||||
screen_lbl = "NotificationPreview";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Notifications:
|
||||
screen_lbl = "Notifications";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Timer:
|
||||
screen_lbl = "Timer";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Alarm:
|
||||
screen_lbl = "Alarm";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::FlashLight:
|
||||
screen_lbl = "FlashLight";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::BatteryInfo:
|
||||
screen_lbl = "BatteryInfo";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Music:
|
||||
screen_lbl = "Music";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Paint:
|
||||
screen_lbl = "Paint";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Paddle:
|
||||
screen_lbl = "Paddle";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Twos:
|
||||
screen_lbl = "Twos";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::HeartRate:
|
||||
screen_lbl = "HeartRate";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Navigation:
|
||||
screen_lbl = "Navigation";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::StopWatch:
|
||||
screen_lbl = "StopWatch";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Metronome:
|
||||
screen_lbl = "Metronome";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Motion:
|
||||
screen_lbl = "Motion";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Steps:
|
||||
screen_lbl = "Steps";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Weather:
|
||||
screen_lbl = "Weather";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::PassKey:
|
||||
screen_lbl = "PassKey";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::QuickSettings:
|
||||
screen_lbl = "QuickSettings";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Settings:
|
||||
screen_lbl = "Settings";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingWatchFace:
|
||||
screen_lbl = "SettingWatchFace";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingTimeFormat:
|
||||
screen_lbl = "SettingTimeFormat";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingDisplay:
|
||||
screen_lbl = "SettingDisplay";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingWakeUp:
|
||||
screen_lbl = "SettingWakeUp";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingSteps:
|
||||
screen_lbl = "SettingSteps";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingSetDate:
|
||||
screen_lbl = "SettingSetDate";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingSetTime:
|
||||
screen_lbl = "SettingSetTime";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingChimes:
|
||||
screen_lbl = "SettingChimes";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::SettingShakeThreshold:
|
||||
screen_lbl = "SettingThreshold";
|
||||
break;
|
||||
case Pinetime::Applications::Apps::Error:
|
||||
screen_lbl = "Error";
|
||||
break;
|
||||
//case Pinetime::Applications::Apps::Weather:
|
||||
// screen_lbl = "Weather";
|
||||
// break;
|
||||
default:
|
||||
screen_lbl = "unkown screen";
|
||||
}
|
||||
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_static(label, screen_lbl);
|
||||
lv_obj_align(label, nullptr, LV_ALIGN_CENTER, 0, -20);
|
||||
}
|
||||
|
||||
Missing::~Missing() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
18
sim/displayapp/screens/Missing.h
Normal file
18
sim/displayapp/screens/Missing.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/Apps.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
namespace Screens {
|
||||
|
||||
class Missing : public Screen {
|
||||
public:
|
||||
Missing(DisplayApp* app, Pinetime::Applications::Apps app_key);
|
||||
~Missing() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user