When a full screen refresh is done, apply a vertical scroll during the refresh. This makes the transition from one screen the another one smoother, even if the refresh rate is slow.

This commit is contained in:
JF
2020-03-08 21:46:25 +01:00
parent d834f40c10
commit 0a5cd60fe8
212 changed files with 89114 additions and 32 deletions

View File

@@ -117,19 +117,19 @@ void DisplayApp::Refresh() {
OnTouchEvent();
break;
case Messages::ButtonPushed:
if(!currentScreen->OnButtonPushed()) {
systemTask.PushMessage(System::SystemTask::Messages::GoToSleep);
}
// currentScreen.reset(nullptr);
// if(toggle) {
// modal.Show();
//// currentScreen.reset(new Screens::Tile(this));
// toggle = false;
// } else {
// modal.Hide();
//// currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController));
// toggle = true;
// if(!currentScreen->OnButtonPushed()) {
// systemTask.PushMessage(System::SystemTask::Messages::GoToSleep);
// }
lvgl.SetFullRefresh();
lv_disp_set_direction(lv_disp_get_default(), 0);
currentScreen.reset(nullptr);
if(toggle) {
currentScreen.reset(new Screens::Tile(this));
toggle = false;
} else {
currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController));
toggle = true;
}
break;
}
@@ -140,6 +140,7 @@ void DisplayApp::RunningState() {
// clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime());
if(!currentScreen->Refresh()) {
lvgl.SetFullRefresh();
currentScreen.reset(nullptr);
switch(nextApp) {
case Apps::None:

View File

@@ -64,21 +64,95 @@ void LittleVgl::InitTouchpad() {
lv_indev_drv_register(&indev_drv);
}
void LittleVgl::SetFullRefresh() {
fullRefresh = true;
}
void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) {
ulTaskNotifyTake(pdTRUE, 500);
auto x = area->x1;
auto y = area->y1;
auto width = (area->x2-area->x1)+1;
auto height = (area->y2-area->y1)+1;
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height*2) ;
// TODO refactore and remove duplicated code
uint16_t x, y, y1, y2, width, height = 0;
if(fullRefresh) {
if(scrollDirection == LittleVgl::ScrollDirections::Down) {
if(area->y2 == visibleNbLines-1) {
writeOffset = ((writeOffset + totalNbLines) - visibleNbLines) % totalNbLines;
}
x = area->x1;
width = (area->x2 - area->x1) + 1;
y1 = (area->y1 + writeOffset) % totalNbLines;
y2 = (area->y2 + writeOffset) % totalNbLines;
y = y1;
height = (y2 - y1) + 1;
if(area->y2 < visibleNbLines - 1) {
uint16_t toScroll = 0;
if(area->y1 == 0) {
toScroll = height*2;
fullRefresh = false;
lv_disp_set_direction(lv_disp_get_default(), 0);
} else {
toScroll = height;
}
if(scrollOffset >= toScroll)
scrollOffset -= toScroll;
else {
toScroll -= scrollOffset;
scrollOffset = (totalNbLines) - toScroll;
}
lcd.VerticalScrollDefinition(0, 320, 0);
lcd.VerticalScrollStartAddress(scrollOffset);
}
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height*2) ;
} else {
if(area->y1 == 0) {
writeOffset = (writeOffset + visibleNbLines) % totalNbLines;
}
x = area->x1;
width = (area->x2 - area->x1) + 1;
y1 = (area->y1 + writeOffset) % totalNbLines;
y2 = (area->y2 + writeOffset) % totalNbLines;
y = y1;
height = (y2 - y1) + 1;
if(area->y1 > 0) {
if(area->y2 == visibleNbLines -1) {
scrollOffset += (height * 2);
fullRefresh = false;
lv_disp_set_direction(lv_disp_get_default(), 0);
} else {
scrollOffset += height;
}
scrollOffset = scrollOffset % totalNbLines;
lcd.VerticalScrollDefinition(0, 320, 0);
lcd.VerticalScrollStartAddress(scrollOffset);
}
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(reinterpret_cast<const uint8_t *>(color_p), width * height*2);
}
} else {
x = area->x1;
y = area->y1;
width = (area->x2 - area->x1) + 1;
height = (area->y2 - area->y1) + 1;
lcd.BeginDrawBuffer(x, y, width, height);
lcd.NextDrawBuffer(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);
}
bool LittleVgl::GetTouchPadInfo(lv_indev_data_t *ptr) {
auto info = touchPanel.GetTouchInfo();
@@ -715,3 +789,4 @@ void LittleVgl::InitThemeWindow() {
// theme.style.win.btn.rel = &lv_style_transp;
// theme.style.win.btn.pr = &win_btn_pr;
}

View File

@@ -15,10 +15,15 @@ namespace Pinetime {
class LittleVgl {
public:
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 FlushDisplay(const lv_area_t * area, lv_color_t * color_p);
bool GetTouchPadInfo(lv_indev_data_t *ptr);
void SetFullRefresh();
private:
void InitDisplay();
void InitTouchpad();
@@ -94,6 +99,15 @@ namespace Pinetime {
lv_style_t win_btn_pr;
bool firstTouch = true;
bool fullRefresh = false;
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; }
enum class ScrollDirections {Unknown, Up, Down};
ScrollDirections scrollDirection = ScrollDirections::Up;
uint16_t writeOffset = 0;
uint16_t scrollOffset = 0;
};
}
}