From 3405f85a6a8a0d9202d9a2ad847ce7f828d9e5a1 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 15 Mar 2015 22:02:33 -0700 Subject: [PATCH 1/6] Reduce size of menu code - Get rid of _selected functions, passing selected state instead --- Marlin/dogm_lcd_implementation.h | 104 +++---- Marlin/ultralcd.cpp | 108 ++++--- .../ultralcd_implementation_hitachi_HD44780.h | 288 ++++++------------ 3 files changed, 193 insertions(+), 307 deletions(-) diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index c1b5d2b82..c1df1cce4 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -282,7 +282,7 @@ static void lcd_implementation_status_screen() { } static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) { - if ((pr_char == '>') || (pr_char == LCD_STR_UPLEVEL[0] )) { + if ((pr_char == '>') || (pr_char == LCD_STR_UPLEVEL[0])) { u8g.setColorIndex(1); // black on white u8g.drawBox (0, row*DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT); u8g.setColorIndex(0); // following text must be white on black @@ -293,29 +293,29 @@ static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) { u8g.setPrintPos(START_ROW * DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT); } -static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char) { +static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) { char c; uint8_t n = LCD_WIDTH - 2; - lcd_implementation_mark_as_selected(row, pre_char); + lcd_implementation_mark_as_selected(row, sel ? pre_char : ' '); - while((c = pgm_read_byte(pstr))) { + while ((c = pgm_read_byte(pstr))) { u8g.print(c); pstr++; n--; } - while(n--) u8g.print(' '); + while (n--) u8g.print(' '); u8g.print(post_char); u8g.print(' '); } -static void _drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, const char* data, bool pgm) { +static void _drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, const char* data, bool pgm) { char c; uint8_t n = LCD_WIDTH - 2 - (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data))); - lcd_implementation_mark_as_selected(row, pre_char); + lcd_implementation_mark_as_selected(row, sel ? '>' : ' '); - while( (c = pgm_read_byte(pstr))) { + while ((c = pgm_read_byte(pstr))) { u8g.print(c); pstr++; n--; @@ -325,47 +325,29 @@ static void _drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char p if (pgm) { lcd_printPGM(data); } else { u8g.print(data); } } -#define lcd_implementation_drawmenu_setting_edit_generic(row, pstr, pre_char, data) _drawmenu_setting_edit_generic(row, pstr, pre_char, data, false) -#define lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, pre_char, data) _drawmenu_setting_edit_generic(row, pstr, pre_char, data, true) - -#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float43_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float43(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) -#define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) +#define lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, false) +#define lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, true) + +#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) //Add version for callback functions -#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float43_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float43(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) -#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) +#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) void lcd_implementation_drawedit(const char* pstr, char* value) { uint8_t rows = 1; @@ -396,19 +378,19 @@ void lcd_implementation_drawedit(const char* pstr, char* value) { u8g.print(value); } -static void _drawmenu_sd(uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir, bool isSelected) { +static void _drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir) { char c; uint8_t n = LCD_WIDTH - 1; - if (longFilename[0] != '\0') { + if (longFilename[0]) { filename = longFilename; longFilename[n] = '\0'; } - lcd_implementation_mark_as_selected(row, ((isSelected) ? '>' : ' ')); + lcd_implementation_mark_as_selected(row, sel ? '>' : ' '); if (isDir) u8g.print(LCD_STR_FOLDER[0]); - while((c = *filename) != '\0') { + while ((c = *filename)) { u8g.print(c); filename++; n--; @@ -416,19 +398,13 @@ static void _drawmenu_sd(uint8_t row, const char* pstr, const char* filename, ch while(n--) u8g.print(' '); } -#define lcd_implementation_drawmenu_sdfile_selected(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, false, true) -#define lcd_implementation_drawmenu_sdfile(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, false, false) -#define lcd_implementation_drawmenu_sddirectory_selected(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, true, true) -#define lcd_implementation_drawmenu_sddirectory(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, true, false) - -#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) -#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0]) -#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') -#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') -#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') -#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') +#define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false) +#define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, true) + +#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) +#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) +#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') +#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') static void lcd_implementation_quick_feedback() { #if BEEPER > -1 diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 8575abbd0..6a0d8cf8e 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -116,64 +116,84 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l /* Helper macros for menus */ + +/** + * START_MENU generates the init code for a menu function + */ #define START_MENU() do { \ - encoderRateMultiplierEnabled = false; \ - if (encoderPosition > 0x8000) encoderPosition = 0; \ - if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM < currentMenuViewOffset) currentMenuViewOffset = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\ - uint8_t _lineNr = currentMenuViewOffset, _menuItemNr; \ - bool wasClicked = LCD_CLICKED;\ - for(uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \ - _menuItemNr = 0; + encoderRateMultiplierEnabled = false; \ + if (encoderPosition > 0x8000) encoderPosition = 0; \ + uint8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \ + if (encoderLine < currentMenuViewOffset) currentMenuViewOffset = encoderLine; \ + uint8_t _lineNr = currentMenuViewOffset, _menuItemNr; \ + bool wasClicked = LCD_CLICKED, itemSelected; \ + if (wasClicked) lcd_quick_feedback(); \ + for (uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \ + _menuItemNr = 0; + +/** + * MENU_ITEM generates draw & handler code for a menu item, potentially calling: + * + * lcd_implementation_drawmenu_[type](sel, row, label, arg3...) + * menu_action_[type](arg3...) + * + * Examples: + * MENU_ITEM(back, MSG_WATCH, lcd_status_screen) + * lcd_implementation_drawmenu_back(sel, row, PSTR(MSG_WATCH), lcd_status_screen) + * menu_action_back(lcd_status_screen) + * + * MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause) + * lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause) + * menu_action_function(lcd_sdcard_pause) + * + * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999) + * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedmultiply, 10, 999) + * lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedmultiply, 10, 999) + * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedmultiply, 10, 999) + * + */ #define MENU_ITEM(type, label, args...) do { \ - if (_menuItemNr == _lineNr) { \ - if (lcdDrawUpdate) { \ - const char* _label_pstr = PSTR(label); \ - if ((encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) { \ - lcd_implementation_drawmenu_ ## type ## _selected (_drawLineNr, _label_pstr , ## args ); \ - }else{\ - lcd_implementation_drawmenu_ ## type (_drawLineNr, _label_pstr , ## args ); \ - }\ - }\ - if (wasClicked && (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) {\ - lcd_quick_feedback(); \ - menu_action_ ## type ( args ); \ - return;\ - }\ - }\ - _menuItemNr++;\ + if (_menuItemNr == _lineNr) { \ + itemSelected = encoderLine == _menuItemNr; \ + if (lcdDrawUpdate) \ + lcd_implementation_drawmenu_ ## type(itemSelected, _drawLineNr, PSTR(label), ## args); \ + if (wasClicked && itemSelected) { \ + menu_action_ ## type(args); \ + return; \ + } \ + } \ + _menuItemNr++; \ } while(0) + #ifdef ENCODER_RATE_MULTIPLIER + /** + * MENU_MULTIPLIER_ITEM generates drawing and handling code for a multiplier menu item + */ #define MENU_MULTIPLIER_ITEM(type, label, args...) do { \ if (_menuItemNr == _lineNr) { \ - if (lcdDrawUpdate) { \ - const char* _label_pstr = PSTR(label); \ - if ((encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) { \ - lcd_implementation_drawmenu_ ## type ## _selected (_drawLineNr, _label_pstr , ## args ); \ - } \ - else { \ - lcd_implementation_drawmenu_ ## type (_drawLineNr, _label_pstr , ## args ); \ - } \ - } \ - if (wasClicked && (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) { \ - lcd_quick_feedback(); \ + itemSelected = encoderLine == _menuItemNr; \ + if (lcdDrawUpdate) \ + lcd_implementation_drawmenu_ ## type(itemSelected, _drawLineNr, PSTR(label), ## args); \ + if (wasClicked && itemSelected) { \ encoderRateMultiplierEnabled = true; \ lastEncoderMovementMillis = 0; \ - menu_action_ ## type ( args ); \ + menu_action_ ## type(args); \ return; \ } \ } \ _menuItemNr++; \ } while(0) #endif //ENCODER_RATE_MULTIPLIER + #define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0) -#define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args ) -#define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args ) +#define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args) +#define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) #ifdef ENCODER_RATE_MULTIPLIER - #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args ) - #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args ) + #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label), ## args) + #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) #else //!ENCODER_RATE_MULTIPLIER - #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args ) - #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args ) + #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args) + #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) #endif //!ENCODER_RATE_MULTIPLIER #define END_MENU() \ if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; \ @@ -461,9 +481,9 @@ static void lcd_tune_menu() { #if TEMP_SENSOR_BED != 0 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15); #endif - MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255); - MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999); - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F0, &extruder_multiply[0], 10, 999); + MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255); + MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999); + MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F0, &extruder_multiply[0], 10, 999); #if TEMP_SENSOR_1 != 0 MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F1, &extruder_multiply[1], 10, 999); #endif diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h index 979f23615..1f8bcb826 100644 --- a/Marlin/ultralcd_implementation_hitachi_HD44780.h +++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h @@ -610,214 +610,104 @@ static void lcd_implementation_status_screen() lcd.print(lcd_status_message); } -static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char) -{ - char c; - //Use all characters in narrow LCDs - #if LCD_WIDTH < 20 - uint8_t n = LCD_WIDTH - 1 - 1; - #else - uint8_t n = LCD_WIDTH - 1 - 2; - #endif - lcd.setCursor(0, row); - lcd.print(pre_char); - while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) - { - lcd.print(c); - pstr++; - if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--; - } - while(n--) - lcd.print(' '); - lcd.print(post_char); - lcd.print(' '); + +static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) { + char c; + uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + lcd.print(c); + pstr++; + if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--; + } + while(n--) lcd.print(' '); + lcd.print(post_char); + lcd.print(' '); } -static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data) -{ - char c; - //Use all characters in narrow LCDs - #if LCD_WIDTH < 20 - uint8_t n = LCD_WIDTH - 1 - 1 - lcd_strlen(data); - #else - uint8_t n = LCD_WIDTH - 1 - 2 - lcd_strlen(data); - #endif - lcd.setCursor(0, row); - lcd.print(pre_char); - while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) - { - lcd.print(c); - pstr++; - if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--; - } - lcd.print(':'); - while(n--) - lcd.print(' '); - lcd.print(data); +static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char* data) { + char c; + uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen(data); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + lcd.print(c); + pstr++; + if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--; + } + lcd.print(':'); + while (n--) lcd.print(' '); + lcd.print(data); } -static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data) -{ - char c; - //Use all characters in narrow LCDs - #if LCD_WIDTH < 20 - uint8_t n = LCD_WIDTH - 1 - 1 - lcd_strlen_P(data); - #else - uint8_t n = LCD_WIDTH - 1 - 2 - lcd_strlen_P(data); - #endif - lcd.setCursor(0, row); - lcd.print(pre_char); - while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) ) - { - lcd.print(c); - pstr++; - if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--; - } - lcd.print(':'); - while(n--) - lcd.print(' '); - lcd_printPGM(data); +static void lcd_implementation_drawmenu_setting_edit_generic_P(bool sel, uint8_t row, const char* pstr, char pre_char, const char* data) { + char c; + uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen_P(data); + lcd.setCursor(0, row); + lcd.print(sel ? pre_char : ' '); + while ((c = pgm_read_byte(pstr)) && n > 0) { + lcd.print(c); + pstr++; + if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--; + } + lcd.print(':'); + while (n--) lcd.print(' '); + lcd_printPGM(data); } -#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float43_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float43(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) -#define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) +#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr43(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) //Add version for callback functions -#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float43_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float43(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) -#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) -#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) - - -void lcd_implementation_drawedit(const char* pstr, char* value) -{ - lcd.setCursor(1, 1); - lcd_printPGM(pstr); - lcd.print(':'); - #if LCD_WIDTH < 20 - lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1); - #else - lcd.setCursor(LCD_WIDTH -1 - lcd_strlen(value), 1); - #endif - lcd.print(value); -} -static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 1; - lcd.setCursor(0, row); - lcd.print('>'); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-1] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); +#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr43(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +void lcd_implementation_drawedit(const char* pstr, char* value) { + lcd.setCursor(1, 1); + lcd_printPGM(pstr); + lcd.print(':'); + lcd.setCursor(LCD_WIDTH - (LCD_WIDTH < 20 ? 0 : 1) - lcd_strlen(value), 1); + lcd.print(value); } -static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 1; - lcd.setCursor(0, row); - lcd.print(' '); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-1] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); +static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat) { + char c; + uint8_t n = LCD_WIDTH - concat; + lcd.setCursor(0, row); + lcd.print(sel ? '>' : ' '); + if (longFilename[0]) { + filename = longFilename; + longFilename[n] = '\0'; + } + while ((c = *filename) && n > 0) { + lcd.print(c); + filename++; + n--; + } + while (n--) lcd.print(' '); } -static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 2; - lcd.setCursor(0, row); - lcd.print('>'); - lcd.print(LCD_STR_FOLDER[0]); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-2] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); + +static void lcd_implementation_drawmenu_sdfile(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) { + lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 1); } -static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 2; - lcd.setCursor(0, row); - lcd.print(' '); - lcd.print(LCD_STR_FOLDER[0]); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-2] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd.print(c); - filename++; - n--; - } - while(n--) - lcd.print(' '); +static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) { + lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2); } -#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) -#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0]) -#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') -#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') -#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ') -#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ') +#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) +#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) +#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, ' ', ' ') +#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, ' ', ' ') static void lcd_implementation_quick_feedback() { From 7629c4f05c59004759a8e41e8aedd335cff2961f Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 15 Mar 2015 22:54:54 -0700 Subject: [PATCH 2/6] Cleanup for menu optimization - Compare pr_char to space - Fewer calls to lcd_strlen --- Marlin/dogm_lcd_implementation.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index c1df1cce4..a488b01b3 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -282,7 +282,7 @@ static void lcd_implementation_status_screen() { } static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) { - if ((pr_char == '>') || (pr_char == LCD_STR_UPLEVEL[0])) { + if (pr_char != ' ') { u8g.setColorIndex(1); // black on white u8g.drawBox (0, row*DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT); u8g.setColorIndex(0); // following text must be white on black @@ -351,22 +351,22 @@ static void _drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* ps void lcd_implementation_drawedit(const char* pstr, char* value) { uint8_t rows = 1; - uint8_t lcd_width = LCD_WIDTH; - uint8_t char_width = DOG_CHAR_WIDTH; + uint8_t lcd_width = LCD_WIDTH, char_width = DOG_CHAR_WIDTH; + uint8_t vallen = lcd_strlen(value); #ifdef USE_BIG_EDIT_FONT if (lcd_strlen_P(pstr) <= LCD_WIDTH_EDIT - 1) { u8g.setFont(FONT_MENU_EDIT); lcd_width = LCD_WIDTH_EDIT + 1; char_width = DOG_CHAR_WIDTH_EDIT; - if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - lcd_strlen(value)) rows = 2; + if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - vallen) rows = 2; } else { u8g.setFont(FONT_MENU); } #endif - if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - lcd_strlen(value)) rows = 2; + if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - vallen) rows = 2; const float kHalfChar = DOG_CHAR_HEIGHT_EDIT / 2; float rowHeight = u8g.getHeight() / (rows + 1); // 1/(rows+1) = 1/2 or 1/3 @@ -374,7 +374,7 @@ void lcd_implementation_drawedit(const char* pstr, char* value) { u8g.setPrintPos(0, rowHeight + kHalfChar); lcd_printPGM(pstr); u8g.print(':'); - u8g.setPrintPos((lcd_width-1-lcd_strlen(value)) * char_width, rows * rowHeight + kHalfChar); + u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar); u8g.print(value); } From e650d4044ede9b8e44bf84e9bea6b257b0503d8d Mon Sep 17 00:00:00 2001 From: alexborro Date: Thu, 19 Mar 2015 14:16:18 -0300 Subject: [PATCH 3/6] Fix "Stop Print" function in the LCD menu When one hit "Stop Print" option in LCD menu, the command buffer was not cleared. The printer keep moving until the buffer has been emptied. Actually I could not clear the command buffer as well.. I don't know why, it doesnt work as expected. I need to implement a routine inside Stepper ISR to handle such situation. --- Marlin/cardreader.cpp | 1 - Marlin/stepper.cpp | 13 +++++++++++++ Marlin/ultralcd.cpp | 7 +------ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp index a51d77bf0..125caab01 100644 --- a/Marlin/cardreader.cpp +++ b/Marlin/cardreader.cpp @@ -504,7 +504,6 @@ void CardReader::printingHasFinished() { startFileprint(); } else { - quickStop(); file.close(); sdprinting = false; if (SD_FINISHED_STEPPERRELEASE) { diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index e9c58e9f4..1c79ea3b4 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -46,6 +46,7 @@ block_t *current_block; // A pointer to the block currently being traced // Variables used by The Stepper Driver Interrupt static unsigned char out_bits; // The next stepping-bits to be output +static unsigned int cleaning_buffer_counter; // Counter variables for the bresenham line tracer static long counter_x, counter_y, counter_z, counter_e; @@ -346,6 +347,17 @@ FORCE_INLINE void trapezoid_generator_reset() { // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse. // It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. ISR(TIMER1_COMPA_vect) { + + if(cleaning_buffer_counter) + { + current_block = NULL; + plan_discard_current_block(); + if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enquecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + cleaning_buffer_counter--; + OCR1A = 200; + return; + } + // If there is no current block, attempt to pop one from the buffer if (!current_block) { // Anything in the buffer? @@ -972,6 +984,7 @@ void finishAndDisableSteppers() { } void quickStop() { + cleaning_buffer_counter = 5000; DISABLE_STEPPER_DRIVER_INTERRUPT(); while (blocks_queued()) plan_discard_current_block(); current_block = NULL; diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index f6edc42e8..c0105db43 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -349,16 +349,11 @@ static void lcd_sdcard_pause() { card.pauseSDPrint(); } static void lcd_sdcard_resume() { card.startFileprint(); } static void lcd_sdcard_stop() { + quickStop(); card.sdprinting = false; card.closefile(); - quickStop(); - if (SD_FINISHED_STEPPERRELEASE) { - enquecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); - } autotempShutdown(); - cancel_heatup = true; - lcd_setstatus(MSG_PRINT_ABORTED); } From 15d29efad506bfd4351b6060d09fe09663074fe2 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 19 Mar 2015 13:40:36 -0700 Subject: [PATCH 4/6] Pass sel to lcd_implementation_mark_as_selected - Pass selected state directly to lcd_implementation_mark_as_selected - Rename sel function parameter - Include a minor fix for SdBaseFile.h --- Marlin/SdBaseFile.h | 4 ++-- Marlin/dogm_lcd_implementation.h | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Marlin/SdBaseFile.h b/Marlin/SdBaseFile.h index b0e77ecb4..dea299a64 100644 --- a/Marlin/SdBaseFile.h +++ b/Marlin/SdBaseFile.h @@ -171,9 +171,9 @@ static inline uint8_t FAT_SECOND(uint16_t fatTime) { return 2*(fatTime & 0X1F); } /** Default date for file timestamps is 1 Jan 2000 */ -uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | BIT(5) | 1; +uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1; /** Default time for file timestamp is 1 am */ -uint16_t const FAT_DEFAULT_TIME = BIT(11); +uint16_t const FAT_DEFAULT_TIME = (1 << 11); //------------------------------------------------------------------------------ /** * \class SdBaseFile diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index 83c3b3f2b..ff63fe126 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -282,8 +282,8 @@ static void lcd_implementation_status_screen() { #endif } -static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) { - if (pr_char != ' ') { +static void lcd_implementation_mark_as_selected(uint8_t row, bool isSelected) { + if (isSelected) { u8g.setColorIndex(1); // black on white u8g.drawBox (0, row*DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT); u8g.setColorIndex(0); // following text must be white on black @@ -294,11 +294,11 @@ static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) { u8g.setPrintPos(START_ROW * DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT); } -static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) { +static void lcd_implementation_drawmenu_generic(bool isSelected, uint8_t row, const char* pstr, char pre_char, char post_char) { char c; uint8_t n = LCD_WIDTH - 2; - lcd_implementation_mark_as_selected(row, sel ? pre_char : ' '); + lcd_implementation_mark_as_selected(row, isSelected); while ((c = pgm_read_byte(pstr))) { u8g.print(c); @@ -310,11 +310,11 @@ static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const cha u8g.print(' '); } -static void _drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, const char* data, bool pgm) { +static void _drawmenu_setting_edit_generic(bool isSelected, uint8_t row, const char* pstr, const char* data, bool pgm) { char c; uint8_t n = LCD_WIDTH - 2 - (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data))); - lcd_implementation_mark_as_selected(row, sel ? '>' : ' '); + lcd_implementation_mark_as_selected(row, isSelected); while ((c = pgm_read_byte(pstr))) { u8g.print(c); @@ -379,7 +379,7 @@ void lcd_implementation_drawedit(const char* pstr, char* value) { u8g.print(value); } -static void _drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir) { +static void _drawmenu_sd(bool isSelected, uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir) { char c; uint8_t n = LCD_WIDTH - 1; @@ -388,7 +388,7 @@ static void _drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* fi longFilename[n] = '\0'; } - lcd_implementation_mark_as_selected(row, sel ? '>' : ' '); + lcd_implementation_mark_as_selected(row, isSelected); if (isDir) u8g.print(LCD_STR_FOLDER[0]); while ((c = *filename)) { From 90ba61b9b8a5229d7e5df8edb63474be2ae7801b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 19 Mar 2015 13:49:06 -0700 Subject: [PATCH 5/6] Include indicator for new drawmenu_generic In the new method we pass the character that should be used for selected state, not the character to print always. --- Marlin/ultralcd_implementation_hitachi_HD44780.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h index 1f8bcb826..0ee097184 100644 --- a/Marlin/ultralcd_implementation_hitachi_HD44780.h +++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h @@ -706,8 +706,8 @@ static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const } #define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]) #define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]) -#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, ' ', ' ') -#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, ' ', ' ') +#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') +#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ') static void lcd_implementation_quick_feedback() { From 7279e4f82fe4047062d8729b6d710e9a7c2d8e36 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 19 Mar 2015 14:01:33 -0700 Subject: [PATCH 6/6] Small code tweaks re lcd.print --- Marlin/dogm_lcd_implementation.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index ff63fe126..27734b866 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -139,7 +139,7 @@ static void lcd_implementation_init() u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT*3/2, STRING_SPLASH_LINE1); u8g.drawStr(txt2X, u8g.getHeight() - DOG_CHAR_HEIGHT*1/2, STRING_SPLASH_LINE2); #endif - } while(u8g.nextPage()); + } while (u8g.nextPage()); } static void lcd_implementation_clear() { } // Automatically cleared by Picture Loop @@ -222,7 +222,7 @@ static void lcd_implementation_status_screen() { int per = ((fanSpeed + 1) * 100) / 256; if (per) { u8g.print(itostr3(per)); - u8g.print("%"); + u8g.print('%'); } else #endif @@ -235,7 +235,7 @@ static void lcd_implementation_status_screen() { u8g.drawBox(0,29,128,10); u8g.setColorIndex(0); // white on black u8g.setPrintPos(2,37); - u8g.print("X"); + u8g.print('X'); u8g.drawPixel(8,33); u8g.drawPixel(8,35); u8g.setPrintPos(10,37); @@ -247,7 +247,7 @@ static void lcd_implementation_status_screen() { u8g.setPrintPos(51,37); u8g.print(ftostr31ns(current_position[Y_AXIS])); u8g.setPrintPos(83,37); - u8g.print("Z"); + u8g.print('Z'); u8g.drawPixel(89,33); u8g.drawPixel(89,35); u8g.setPrintPos(91,37); @@ -285,7 +285,7 @@ static void lcd_implementation_status_screen() { static void lcd_implementation_mark_as_selected(uint8_t row, bool isSelected) { if (isSelected) { u8g.setColorIndex(1); // black on white - u8g.drawBox (0, row*DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT); + u8g.drawBox(0, row * DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT); u8g.setColorIndex(0); // following text must be white on black } else { @@ -322,7 +322,7 @@ static void _drawmenu_setting_edit_generic(bool isSelected, uint8_t row, const c n--; } u8g.print(':'); - while(n--) u8g.print(' '); + while (n--) u8g.print(' '); if (pgm) { lcd_printPGM(data); } else { u8g.print(data); } } @@ -396,7 +396,7 @@ static void _drawmenu_sd(bool isSelected, uint8_t row, const char* pstr, const c filename++; n--; } - while(n--) u8g.print(' '); + while (n--) u8g.print(' '); } #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false)