diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index f508df7d1..2bbfe2c7c 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -937,7 +937,6 @@ void CardReader::presort() { _delay(300); lcd_clear(); #endif - lcd_scrollTimer.start(); lcd_update(2); KEEPALIVE_STATE(NOT_BUSY); lcd_timeoutToStatus.start(); diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 1041aba8e..ecb25c2a8 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -645,7 +645,6 @@ lcd_lcdupdate_func_t lcd_lcdupdate_func = 0; static ShortTimer buttonBlanking; ShortTimer longPressTimer; LongTimer lcd_timeoutToStatus; -ShortTimer lcd_scrollTimer; //! @brief Was button clicked? diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 81f27bb22..cd180a441 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -102,8 +102,6 @@ extern uint8_t lcd_update_enabled; extern LongTimer lcd_timeoutToStatus; -extern ShortTimer lcd_scrollTimer; - extern uint32_t lcd_next_update_millis; extern uint8_t lcd_status_update_delay; diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 55ea82b59..3ab409956 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -33,7 +33,6 @@ uint8_t menu_top = 0; uint8_t menu_clicked = 0; -uint8_t menu_entering = 0; uint8_t menu_leaving = 0; menu_func_t menu_menu = 0; @@ -55,7 +54,6 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo // This ensures, that the menu entered will find out, that it shall initialize itself. memset(&menu_data, 0, sizeof(menu_data)); } - menu_entering = 1; //next menu that supports entering will clear this flag on first enter. Used for initializing some menus only one time. if (feedback) lcd_quick_feedback(); } else @@ -112,15 +110,6 @@ void menu_back_no_reset(void) } } -void menu_back_scroll(int scrollback) -{ - if (menu_depth > 0) - { - menu_depth--; - menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position + scrollback, false, true); - } -} - void menu_back_if_clicked(void) { if (lcd_clicked()) @@ -156,16 +145,6 @@ void menu_submenu_no_reset(menu_func_t submenu) } } -void menu_submenu_scroll(menu_func_t submenu) -{ - if (menu_depth < MENU_DEPTH_MAX) - { - menu_stack[menu_depth].menu = menu_menu; - menu_stack[menu_depth++].position = lcd_encoder; - menu_goto(submenu, 0, false, false); - } -} - uint8_t menu_item_ret(void) { lcd_beeper_quick_feedback(); diff --git a/Firmware/menu.h b/Firmware/menu.h index d0595bb3f..180485c7f 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -59,7 +59,6 @@ extern uint8_t menu_top; extern uint8_t menu_clicked; -extern uint8_t menu_entering; extern uint8_t menu_leaving; //function pointer to the currently active menu @@ -79,8 +78,6 @@ extern void menu_back(void); extern void menu_back_no_reset(void); extern void menu_back(uint8_t nLevel); -extern void menu_back_scroll(int scrollback); - extern void menu_back_if_clicked(void); extern void menu_back_if_clicked_fb(void); @@ -88,8 +85,6 @@ extern void menu_back_if_clicked_fb(void); extern void menu_submenu(menu_func_t submenu); extern void menu_submenu_no_reset(menu_func_t submenu); -extern void menu_submenu_scroll(menu_func_t submenu); - extern uint8_t menu_item_ret(void); //extern int menu_draw_item_printf_P(char type_char, const char* format, ...); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2ef0ee9b1..beae6edcb 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -321,58 +321,6 @@ bool bSettings; // flag (i.e. 'fake parameter' const char STR_SEPARATOR[] PROGMEM = "------------"; -typedef struct -{ - uint8_t offset = 0; - bool isDir = 0; - uint8_t row = 0; - const char* scrollPointer; - uint16_t fileCnt; -} _menu_data_scroll_t; -static_assert(sizeof(menu_data)>= sizeof(_menu_data_scroll_t),"_menu_data_scroll_t doesn't fit into menu_data"); - -static void lcd_filename_scroll() //this is a submenu -{ - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - if (menu_entering) - { - menu_entering = 0; //clear entering flag - lcd_scrollTimer.start(); - } - bool rewindFlag = LCD_CLICKED || (lcd_encoder != 0); //go back to sd_menu. - if (rewindFlag == 1) _md->offset = 0; - if (lcd_scrollTimer.expired(300) || rewindFlag) - { - uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); - lcd_set_cursor(0, _md->row); - lcd_print('>'); - if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); - for (; i != 0; i--) - { - char c = *(_md->scrollPointer + _md->offset +((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); - if (c == '\0') - { - lcd_scrollTimer.stop(); - break; //stop at the end of the string - } - else - { - lcd_print(c); - lcd_scrollTimer.start(); - } - } - if (i != 0) //adds spaces if string is incomplete or at the end (instead of null). - { - lcd_space(i); - } - _md->offset++; - } - if (rewindFlag) //go back to sd_menu. - { - lcd_scrollTimer.start(); - menu_back_scroll(lcd_encoder); - } -} static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFilename) { char c; @@ -415,19 +363,19 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) { if (menu_item == menu_line) { - if (lcd_draw_update || !lcd_scrollTimer.running()) + if (lcd_draw_update/* || !lcd_scrollTimer.running() */) { - if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) +/* if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) { // lcd_beeper_quick_feedback(); - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); + _menu_data_sdcard_t* _md = (_menu_data_sdcard_t*)&(menu_data[0]); _md->isDir = 1; _md->row = menu_row; _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; menu_submenu_scroll(lcd_filename_scroll); return 1; //stop menu generation early } - else lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); + else */lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -447,19 +395,9 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { if (menu_item == menu_line) { - if (lcd_draw_update || !lcd_scrollTimer.running()) + if (lcd_draw_update) { - if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) - { - // lcd_beeper_quick_feedback(); - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - _md->isDir = 0; - _md->row = menu_row; - _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; - menu_submenu_scroll(lcd_filename_scroll); - return 1; - } - else lcd_implementation_drawmenu_sdfile(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); + lcd_implementation_drawmenu_sdfile(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -7172,8 +7110,9 @@ static void lcd_sd_refresh() #endif menu_top = 0; lcd_encoder = 0; - lcd_scrollTimer.start(); - menu_entering = 1; + //todo: clear menu data. Resets sdcard_menu state and timer + // lcd_scrollTimer.start(); + // menu_entering = 1; } static void lcd_sd_updir() @@ -7181,8 +7120,8 @@ static void lcd_sd_updir() card.updir(); menu_top = 0; lcd_encoder = 0; - lcd_scrollTimer.start(); - menu_entering = 1; + // lcd_scrollTimer.start(); + // menu_entering = 1; } void lcd_print_stop() @@ -7284,60 +7223,130 @@ void lcd_sdcard_stop() void lcd_sdcard_menu() { - uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - - if (presort_flag == true) { - presort_flag = false; - card.presort(); - lcd_scrollTimer.start(); - lcd_draw_update = 1; - } - if (!lcd_scrollTimer.running()) lcd_scrollTimer.start(); - bool scrollEnter = lcd_scrollTimer.expired(500); - if (lcd_draw_update == 0 && LCD_CLICKED == 0 && !scrollEnter && !menu_entering) - return; // nothing to do (so don't thrash the SD card) - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - if (menu_entering) - { - menu_entering = 0; //clear entering flag - lcd_draw_update = 1; //draw lines again - _md->fileCnt = card.getnrfilenames(); - } - if (!scrollEnter) lcd_scrollTimer.start(); - MENU_BEGIN(); - MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion - card.getWorkDirName(); - if (card.filename[0] == '/') - { + typedef struct + { + uint8_t menuState = 0; //start as uninitialized + uint8_t offset; + bool isDir; + const char* scrollPointer; + uint16_t fileCnt; + uint8_t row; + ShortTimer lcd_scrollTimer; + } _menu_data_sdcard_t; + static_assert(sizeof(menu_data)>= sizeof(_menu_data_sdcard_t),"_menu_data_sdcard_t doesn't fit into menu_data"); + _menu_data_sdcard_t* _md = (_menu_data_sdcard_t*)&(menu_data[0]); + + switch(_md->menuState) + { + case 0: //Initialize menu data + { + if (presort_flag == true) { //used to force resorting if sorting type is changed. + presort_flag = false; + card.presort(); + } + _md->fileCnt = card.getnrfilenames(); + _md->menuState = 1; + } //Begin the first menu state instantly. + case 1: //normal menu structure. + { + if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen. + { + _md->lcd_scrollTimer.start(); + lcd_draw_update = 1; + } + if (_md->lcd_scrollTimer.expired(500) && _md->scrollPointer) //switch to the scrolling state on timeout if a file/dir is selected. + { + _md->menuState = 2; + _md->offset = 0; + _md->lcd_scrollTimer.start(); + lcd_draw_update = 1; //forces last load before switching to state:2. + } + if (lcd_draw_update == 0 && !LCD_CLICKED) return; // nothing to do (so don't thrash the SD card) + + //if we reached this point it means that the encoder moved or clicked or the state is being switched. Reset the scrollTimer. + _md->lcd_scrollTimer.start(); + + _md->scrollPointer = NULL; //clear scrollPointer. Used for differentiating between a file/dir and another menu item that is selected. + + const uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); + MENU_BEGIN(); + MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion + card.getWorkDirName(); + if (card.filename[0] == '/') + { #if SDCARDDETECT == -1 - MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); + MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); #else - if (card.ToshibaFlashAir_isEnabled()) MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); + if (card.ToshibaFlashAir_isEnabled()) MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); //show the refresh option if in flashAir mode. #endif - } else { - MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); - } + } + else MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); //Show the updir button if in a subdir. - for (uint16_t i = 0; i < _md->fileCnt; i++) - { - if (menu_item == menu_line) - { - const uint16_t nr = _md->fileCnt - 1 - i; - #ifdef SDCARD_SORT_ALPHA - if (sdSort == SD_SORT_NONE) card.getfilename(nr); - else card.getfilename_sorted(nr); - #else - card.getfilename(nr); - #endif - if (card.filenameIsDir) - MENU_ITEM_SDDIR(card.filename, card.longFilename); - else - MENU_ITEM_SDFILE(card.filename, card.longFilename); - } else { - MENU_ITEM_DUMMY(); - } - } - MENU_END(); + for (uint16_t i = 0; i < _md->fileCnt; i++) // Every file, from top to bottom. + { + if (menu_item == menu_line) //If the file is on the screen. + { + const uint16_t nr = _md->fileCnt - 1 - i; //file index inversion. + + //load filename to memory. +#ifdef SDCARD_SORT_ALPHA + if (sdSort == SD_SORT_NONE) card.getfilename(nr); + else card.getfilename_sorted(nr); +#else + card.getfilename(nr); +#endif + if (lcd_encoder == menu_item) //If the file is selected. + { + _md->scrollPointer = (card.longFilename[0] == '\0') ? card.filename : card.longFilename; + _md->isDir = card.filenameIsDir; + _md->row = menu_row; + if(_md->menuState == 2) return; //return early if switching states. At this point the selected filename should be loaded into memory. + } + if (card.filenameIsDir) MENU_ITEM_SDDIR(card.filename, card.longFilename); + else MENU_ITEM_SDFILE(card.filename, card.longFilename); + } + else MENU_ITEM_DUMMY(); //dummy item that just increments the internal menu counters. + } + MENU_END(); + } break; + case 2: //scrolling filename + { + const bool rewindFlag = LCD_CLICKED || lcd_draw_update; //flag that says whether the menu should return to state:1. + if (rewindFlag == 1) _md->offset = 0; //redraw once again from the beginning. + if (_md->lcd_scrollTimer.expired(300) || rewindFlag) + { + uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); + lcd_set_cursor(0, _md->row); + lcd_print('>'); + if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); + for (; i != 0; i--) + { + char c = *(_md->scrollPointer + _md->offset +((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); + if (c == '\0') + { + _md->lcd_scrollTimer.stop(); + break; //stop at the end of the string + } + else + { + lcd_print(c); + _md->lcd_scrollTimer.start(); + } + } + if (i != 0) //adds spaces if string is incomplete or at the end (instead of null). + { + lcd_space(i); + } + _md->offset++; + } + if (rewindFlag) //go back to sd_menu. + { + _md->lcd_scrollTimer.stop(); //forces redraw in state:1 + _md->menuState = 1; + } + } break; + default: _md->menuState = 0; //shouldn't ever happen. Anyways, initialize the menu. + } } #ifdef TMC2130 static void lcd_belttest_v() @@ -8686,8 +8695,8 @@ void menu_action_sddirectory(const char* filename) MYSERIAL.println(dir_names[depth]); card.chdir(filename); lcd_encoder = 0; - lcd_scrollTimer.start(); - menu_entering = 1; + // lcd_scrollTimer.start(); + // menu_entering = 1; } /** LCD API **/ @@ -8877,7 +8886,6 @@ void menu_lcd_longpress_func(void) || menu_menu == lcd_main_menu || menu_menu == lcd_preheat_menu || menu_menu == lcd_sdcard_menu - || menu_menu == lcd_filename_scroll || menu_menu == lcd_settings_menu || menu_menu == lcd_control_temperature_menu #if (LANG_MODE != 0) @@ -8885,7 +8893,6 @@ void menu_lcd_longpress_func(void) #endif || menu_menu == lcd_support_menu ){ - if (menu_menu == lcd_filename_scroll) menu_back(); move_menu_scale = 1.0; menu_submenu(lcd_move_z); } else { @@ -8944,8 +8951,6 @@ void menu_lcd_lcdupdate_func(void) { if(menu_menu==lcd_sdcard_menu) menu_back(); - else if (menu_menu==lcd_filename_scroll) - menu_back(2); //back 2 levels. Exit lcd_filename_scroll and lcd sd_card_menu card.release(); LCD_MESSAGERPGM(_i("Card removed"));////MSG_SD_REMOVED }