From 70e9c07b2d888aba3e24aefac174e246e620d2d5 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 5 Mar 2018 23:05:05 -0600 Subject: [PATCH] Fix menu highlight glitch, tweak scrolling code (#9954) --- Marlin/ultralcd.cpp | 57 +++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 790c1180ca..e0c15436a9 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -147,7 +147,10 @@ uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to uint16_t max_display_update_time = 0; #if ENABLED(DOGLCD) - bool drawing_screen = false; + bool drawing_screen, // = false + first_page; +#else + constexpr bool first_page = true; #endif #if ENABLED(DAC_STEPPER_CURRENT) @@ -166,6 +169,7 @@ uint16_t max_display_update_time = 0; #endif bool no_reentry = false; + constexpr int8_t menu_bottom = LCD_HEIGHT - (TALL_FONT_CORRECTION); //////////////////////////////////////////// ///////////////// Menu Tree //////////////// @@ -383,22 +387,21 @@ uint16_t max_display_update_time = 0; * _lcdLineNr is the index of the LCD line (e.g., 0-3) * _menuLineNr is the menu item to draw and process * _thisItemNr is the index of each MENU_ITEM or STATIC_ITEM - * _countedItems is the total number of items in the menu (after one call) + * screen_items is the total number of items in the menu (after one call) */ #define START_SCREEN_OR_MENU(LIMIT) \ ENCODER_DIRECTION_MENUS(); \ ENCODER_RATE_MULTIPLY(false); \ if (encoderPosition > 0x8000) encoderPosition = 0; \ - static int8_t _countedItems = 0; \ - int8_t encoderLine = encoderPosition / (ENCODER_STEPS_PER_MENU_ITEM); \ - if (_countedItems > 0 && encoderLine >= _countedItems - (LIMIT)) { \ - encoderLine = max(0, _countedItems - (LIMIT)); \ + if (first_page) encoderLine = encoderPosition / (ENCODER_STEPS_PER_MENU_ITEM); \ + if (screen_items > 0 && encoderLine >= screen_items - (LIMIT)) { \ + encoderLine = max(0, screen_items - (LIMIT)); \ encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM); \ } #define SCREEN_OR_MENU_LOOP() \ int8_t _menuLineNr = encoderTopLine, _thisItemNr; \ - for (int8_t _lcdLineNr = 0; _lcdLineNr < LCD_HEIGHT - (TALL_FONT_CORRECTION); _lcdLineNr++, _menuLineNr++) { \ + for (int8_t _lcdLineNr = 0; _lcdLineNr < menu_bottom; _lcdLineNr++, _menuLineNr++) { \ _thisItemNr = 0 /** @@ -409,28 +412,22 @@ uint16_t max_display_update_time = 0; * Scroll as-needed to keep the selected line in view. */ #define START_SCREEN() \ - START_SCREEN_OR_MENU(LCD_HEIGHT - (TALL_FONT_CORRECTION)); \ - encoderTopLine = encoderLine; \ + scroll_screen(menu_bottom, false); \ bool _skipStatic = false; \ SCREEN_OR_MENU_LOOP() #define START_MENU() \ - START_SCREEN_OR_MENU(1); \ - screen_changed = false; \ - NOMORE(encoderTopLine, encoderLine); \ - if (encoderLine >= encoderTopLine + LCD_HEIGHT - (TALL_FONT_CORRECTION)) { \ - encoderTopLine = encoderLine - (LCD_HEIGHT - (TALL_FONT_CORRECTION) - 1); \ - } \ + scroll_screen(1, true); \ bool _skipStatic = true; \ SCREEN_OR_MENU_LOOP() #define END_SCREEN() \ } \ - _countedItems = _thisItemNr + screen_items = _thisItemNr #define END_MENU() \ } \ - _countedItems = _thisItemNr; \ + screen_items = _thisItemNr; \ UNUSED(_skipStatic) //////////////////////////////////////////// @@ -632,6 +629,29 @@ uint16_t max_display_update_time = 0; lcd_goto_previous_menu(); } + /** + * Scrolling for menus and other line-based screens + */ + int8_t encoderLine, screen_items; + void scroll_screen(const uint8_t limit, const bool is_menu) { + if (encoderPosition > 0x8000) encoderPosition = 0; + if (first_page) { + encoderLine = encoderPosition / (ENCODER_STEPS_PER_MENU_ITEM); + screen_changed = false; + } + if (screen_items > 0 && encoderLine >= screen_items - limit) { + encoderLine = max(0, screen_items - limit); + encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM); + } + if (is_menu) { + NOMORE(encoderTopLine, encoderLine); + if (encoderLine >= encoderTopLine + menu_bottom) + encoderTopLine = encoderLine - menu_bottom + 1; + } + else + encoderTopLine = encoderLine; + } + #endif // ULTIPANEL /** @@ -5179,11 +5199,12 @@ void lcd_update() { if (do_u8g_loop) { if (!drawing_screen) { // If not already drawing pages u8g.firstPage(); // Start the first page - drawing_screen = 1; // Flag as drawing pages + drawing_screen = first_page = true; // Flag as drawing pages } lcd_setFont(FONT_MENU); // Setup font for every page draw u8g.setColorIndex(1); // And reset the color CURRENTSCREEN(); // Draw and process the current screen + first_page = false; // The screen handler can clear drawing_screen for an action that changes the screen. // If still drawing and there's another page, update max-time and return now.