diff options
| author | JF <jf@codingfield.com> | 2020-03-08 20:46:25 (GMT) |
|---|---|---|
| committer | JF <jf@codingfield.com> | 2020-03-08 20:46:25 (GMT) |
| commit | 0a5cd60fe86149f8958fc546e99f6370cb74950e (patch) | |
| tree | d630a6c66d69d22c53b8011e215e1072875c6a29 /src/DisplayApp | |
| parent | d834f40c1014ac8926af9aaadc434a49e632b000 (diff) | |
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.
Diffstat (limited to 'src/DisplayApp')
| -rw-r--r-- | src/DisplayApp/DisplayApp.cpp | 25 | ||||
| -rw-r--r-- | src/DisplayApp/LittleVgl.cpp | 89 | ||||
| -rw-r--r-- | src/DisplayApp/LittleVgl.h | 16 |
3 files changed, 110 insertions, 20 deletions
diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index d7d62dd..3c980dc 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -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: diff --git a/src/DisplayApp/LittleVgl.cpp b/src/DisplayApp/LittleVgl.cpp index 905c00b..2796daa 100644 --- a/src/DisplayApp/LittleVgl.cpp +++ b/src/DisplayApp/LittleVgl.cpp @@ -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; } + diff --git a/src/DisplayApp/LittleVgl.h b/src/DisplayApp/LittleVgl.h index 40fb180..555f5f0 100644 --- a/src/DisplayApp/LittleVgl.h +++ b/src/DisplayApp/LittleVgl.h @@ -15,10 +15,15 @@ namespace Pinetime { class LittleVgl { public: LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel); - void FlushDisplay(const lv_area_t * area, lv_color_t * color_p); + 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; }; } } |
