void lcd_normal_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{
  if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos = -1;
  if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos = entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;

  uint8_t selIndex =constrain(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM, 0, entryCount-1);
  uint8_t drawOffset;

  lcd_lib_clear();

  switch (languageType) {
  case LANGUAGE_CHINESE:
  case LANGUAGE_KOREAN:
    drawOffset = (49-12*entryCount)/2+1;
    for(int8_t n=0; n<entryCount; n++)
    {
      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';

      if (n == selIndex) {
        lcd_lib_draw_string(54-6, drawOffset+12*n, ptr);
      }else{
        lcd_lib_draw_string(54+6, drawOffset+12*n, ptr+2);
      }
    }
    lcd_lib_draw_hline(0, 127, 53-3);

    break;
  case LANGUAGE_ENGLISH:
    drawOffset = (52-13*entryCount)/2+3;
    for(int8_t n=0; n<entryCount; n++)
    {
      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';
      if (n == selIndex) {
        lcd_lib_draw_string(54, drawOffset+13*n, ptr);
      }else{
        lcd_lib_draw_string(60, drawOffset+13*n, ptr+1);
      }
    }
    lcd_lib_draw_hline(0, 127, 53);
    break;
  default:
    break;
  }

  entryDetailsCallback(selIndex);
}
static void lcd_material_settings_details_callback(uint8_t nr)
{
    char buffer[10];
    buffer[0] = '\0';
    if (nr == 0)
    {
        return;
    }else if (nr == 1)
    {
        int_to_string(material[active_extruder].temperature, buffer, PSTR("C"));
    }else if (nr == 2)
    {
        int_to_string(material[active_extruder].bed_temperature, buffer, PSTR("C"));
    }else if (nr == 3)
    {
        float_to_string(material[active_extruder].diameter, buffer, PSTR("mm"));
    }else if (nr == 4)
    {
        int_to_string(material[active_extruder].fan_speed, buffer, PSTR("%"));
    }else if (nr == 5)
    {
        int_to_string(material[active_extruder].flow, buffer, PSTR("%"));
    }
    lcd_lib_draw_string(5, 53, buffer);
}
static void lcd_material_select_details_callback(uint8_t nr)
{
    uint8_t count = eeprom_read_byte(EEPROM_MATERIAL_COUNT_OFFSET());
    if (nr == 0)
    {
        
    }
    else if (nr <= count)
    {
        char buffer[32];
        char* c = buffer;
        nr -= 1;
        
        if (led_glow_dir)
        {
            c = float_to_string(eeprom_read_float(EEPROM_MATERIAL_DIAMETER_OFFSET(nr)), c, PSTR("mm"));
            while(c < buffer + 10) *c++ = ' ';
            strcpy_P(c, PSTR("Flow:"));
            c += 5;
            c = int_to_string(eeprom_read_word(EEPROM_MATERIAL_FLOW_OFFSET(nr)), c, PSTR("%"));
        }else{
            c = int_to_string(eeprom_read_word(EEPROM_MATERIAL_TEMPERATURE_OFFSET(nr)), c, PSTR("C"));
            *c++ = ' ';
            c = int_to_string(eeprom_read_word(EEPROM_MATERIAL_BED_TEMPERATURE_OFFSET(nr)), c, PSTR("C"));
            while(c < buffer + 10) *c++ = ' ';
            strcpy_P(c, PSTR("Fan: "));
            c += 5;
            c = int_to_string(eeprom_read_byte(EEPROM_MATERIAL_FAN_SPEED_OFFSET(nr)), c, PSTR("%"));
        }
        lcd_lib_draw_string(5, 53, buffer);
    }else{
        lcd_lib_draw_string_centerP(53, PSTR("Modify the settings"));
    }
}
static void lcd_material_settings_details_callback(uint8_t nr)
{
    char buffer[10];
    buffer[0] = '\0';
    if (nr == 0)
    {
        return;
    }else if (nr == 1)
    {
        int_to_string(material[active_extruder].temperature, buffer, PSTR("C"));
#if TEMP_SENSOR_BED != 0
    }else if (nr == 2)
    {
        int_to_string(material[active_extruder].bed_temperature, buffer, PSTR("C"));
#endif
    }else if (nr == 2 + BED_MENU_OFFSET)
    {
        float_to_string(material[active_extruder].diameter, buffer, PSTR("mm"));
    }else if (nr == 3 + BED_MENU_OFFSET)
    {
        int_to_string(material[active_extruder].fan_speed, buffer, PSTR("%"));
    }else if (nr == 4 + BED_MENU_OFFSET)
    {
        int_to_string(material[active_extruder].flow, buffer, PSTR("%"));
#ifdef USE_CHANGE_TEMPERATURE
    }else if (nr == 5 + BED_MENU_OFFSET)
    {
        int_to_string(material[active_extruder].change_temperature, buffer, PSTR("C"));
    }else if (nr == 6 + BED_MENU_OFFSET)
    {
        int_to_string(material[active_extruder].change_preheat_wait_time, buffer, PSTR("Sec"));
#endif
    }
    lcd_lib_draw_string(5, 53, buffer);
}
static void lcd_menu_change_material_select_material_details_callback(uint8_t nr)
{
    char buffer[32];
    char* c = buffer;

    if (led_glow_dir)
    {
        c = float_to_string(eeprom_read_float(EEPROM_MATERIAL_DIAMETER_OFFSET(nr)), c, PSTR("mm"));
        while(c < buffer + 10) *c++ = ' ';
        strcpy_P(c, PSTR("Flow:"));
        c += 5;
        c = int_to_string(eeprom_read_word(EEPROM_MATERIAL_FLOW_OFFSET(nr)), c, PSTR("%"));
    }else{
        c = int_to_string(eeprom_read_word(EEPROM_MATERIAL_TEMPERATURE_OFFSET(nr)), c, PSTR("C"));
#if TEMP_SENSOR_BED != 0
        *c++ = ' ';
        c = int_to_string(eeprom_read_word(EEPROM_MATERIAL_BED_TEMPERATURE_OFFSET(nr)), c, PSTR("C"));
#endif
        while(c < buffer + 10) *c++ = ' ';
        strcpy_P(c, PSTR("Fan: "));
        c += 5;
        c = int_to_string(eeprom_read_byte(EEPROM_MATERIAL_FAN_SPEED_OFFSET(nr)), c, PSTR("%"));
    }
    lcd_lib_draw_string(5, 53, buffer);
}
static void lcd_menu_print_printing()
{
    lcd_question_screen(lcd_menu_print_tune, NULL, PSTR("TUNE"), lcd_menu_print_abort, NULL, PSTR("ABORT"));
    uint8_t progress = card.getFilePos() / ((card.getFileSize() + 123) / 124);
    char buffer[16];
    char* c;
    switch(printing_state)
    {
    default:
        lcd_lib_draw_string_centerP(20, PSTR("Printing:"));
        lcd_lib_draw_string_center(30, card.longFilename);
        break;
    case PRINT_STATE_HEATING:
        lcd_lib_draw_string_centerP(20, PSTR("Heating"));
        c = int_to_string(current_temperature[0], buffer, PSTR("C"));
        *c++ = '/';
        c = int_to_string(target_temperature[0], c, PSTR("C"));
        lcd_lib_draw_string_center(30, buffer);
        break;
    case PRINT_STATE_HEATING_BED:
        lcd_lib_draw_string_centerP(20, PSTR("Heating buildplate"));
        c = int_to_string(current_temperature_bed, buffer, PSTR("C"));
        *c++ = '/';
        c = int_to_string(target_temperature_bed, c, PSTR("C"));
        lcd_lib_draw_string_center(30, buffer);
        break;
    }
    float printTimeMs = (millis() - starttime);
    float printTimeSec = printTimeMs / 1000L;
    float totalTimeMs = float(printTimeMs) * float(card.getFileSize()) / float(card.getFilePos());
    static float totalTimeSmoothSec;
    totalTimeSmoothSec = (totalTimeSmoothSec * 999L + totalTimeMs / 1000L) / 1000L;
    if (isinf(totalTimeSmoothSec))
        totalTimeSmoothSec = totalTimeMs;
    
    if (LCD_DETAIL_CACHE_TIME() == 0 && printTimeSec < 60)
    {
        totalTimeSmoothSec = totalTimeMs / 1000;
        lcd_lib_draw_stringP(5, 10, PSTR("Time left unknown"));
    }else{
        unsigned long totalTimeSec;
        if (printTimeSec < LCD_DETAIL_CACHE_TIME() / 2)
        {
            float f = float(printTimeSec) / float(LCD_DETAIL_CACHE_TIME() / 2);
            totalTimeSec = float(totalTimeSmoothSec) * f + float(LCD_DETAIL_CACHE_TIME()) * (1 - f);
        }else{
            totalTimeSec = totalTimeSmoothSec;
        }
        unsigned long timeLeftSec = totalTimeSec - printTimeSec;
        int_to_time_string(timeLeftSec, buffer);
        lcd_lib_draw_stringP(5, 10, PSTR("Time left"));
        lcd_lib_draw_string(65, 10, buffer);
    }

    lcd_progressbar(progress);
    
    lcd_lib_update_screen();
}
void lcd_scroll_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{
    if (lcd_lib_button_pressed)
		return;//Selection possibly changed the menu, so do not update it this cycle.

    if (lcd_lib_encoder_pos == ENCODER_NO_SELECTION)
        lcd_lib_encoder_pos = 0;

	static int16_t viewPos = 0;
	if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos += entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;
	if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos -= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;

    uint8_t selIndex = uint16_t(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM);

    lcd_lib_clear();

    int16_t targetViewPos = selIndex * 8 - 15;

    int16_t viewDiff = targetViewPos - viewPos;
    viewPos += viewDiff / 4;
    if (viewDiff > 0) { viewPos ++; led_glow = led_glow_dir = 0; }
    if (viewDiff < 0) { viewPos --; led_glow = led_glow_dir = 0; }

    uint8_t drawOffset = 10 - (uint16_t(viewPos) % 8);
    uint8_t itemOffset = uint16_t(viewPos) / 8;
    for(uint8_t n=0; n<6; n++)
    {
        uint8_t itemIdx = n + itemOffset;
        if (itemIdx >= entryCount)
            continue;

        char* ptr = entryNameCallback(itemIdx);
		//ptr[10] = '\0';
		ptr[20] = '\0';
        if (itemIdx == selIndex)
        {
            //lcd_lib_set(3, drawOffset+8*n-1, 62, drawOffset+8*n+7);
            lcd_lib_set(3, drawOffset+8*n-1, 124, drawOffset+8*n+7);
            lcd_lib_clear_string(4, drawOffset+8*n, ptr);
        }else{
            lcd_lib_draw_string(4, drawOffset+8*n, ptr);
        }
    }
    lcd_lib_set(3, 0, 124, 8);
    lcd_lib_clear(3, 47, 124, 63);
    lcd_lib_clear(3, 9, 124, 9);

    lcd_lib_draw_hline(3, 124, 48);

    lcd_lib_clear_string_centerP(1, menuNameP);
    
	entryDetailsCallback(selIndex);
	
    lcd_lib_update_screen();
}
static void lcd_retraction_details(uint8_t nr)
{
    char buffer[16];
    if (nr == 0)
        return;
    else if(nr == 1)
        float_to_string(retract_length, buffer, PSTR("mm"));
    else if(nr == 2)
        int_to_string(retract_feedrate / 60 + 0.5, buffer, PSTR("mm/sec"));
#if EXTRUDERS > 1
    else if(nr == 3)
        int_to_string(extruder_swap_retract_length, buffer, PSTR("mm"));
#endif
    lcd_lib_draw_string(5, 53, buffer);
}
static void tune_item_details_callback(uint8_t nr)
{
    char* c = (char*)lcd_cache;
    if (nr == 2)
        c = int_to_string(feedmultiply, c, PSTR("%"));
    else if (nr == 3)
    {
        c = int_to_string(current_temperature[0], c, PSTR("C"));
        *c++ = '/';
        c = int_to_string(target_temperature[0], c, PSTR("C"));
    }
#if EXTRUDERS > 1
    else if (nr == 4)
    {
        c = int_to_string(current_temperature[1], c, PSTR("C"));
        *c++ = '/';
        c = int_to_string(target_temperature[1], c, PSTR("C"));
    }
#endif
    else if (nr == 3 + EXTRUDERS)
    {
        c = int_to_string(current_temperature_bed, c, PSTR("C"));
        *c++ = '/';
        c = int_to_string(target_temperature_bed, c, PSTR("C"));
    }
    else if (nr == 4 + EXTRUDERS)
        c = int_to_string(int(fanSpeed) * 100 / 255, c, PSTR("%"));
    else if (nr == 5 + EXTRUDERS)
        c = int_to_string(extrudemultiply[0], c, PSTR("%"));
#if EXTRUDERS > 1
    else if (nr == 6 + EXTRUDERS)
        c = int_to_string(extrudemultiply[1], c, PSTR("%"));
#endif
    else if (nr == 7 + EXTRUDERS)
    {
        c = int_to_string(led_brightness_level, c, PSTR("%"));
        if (led_mode == LED_MODE_ALWAYS_ON ||  led_mode == LED_MODE_WHILE_PRINTING || led_mode == LED_MODE_BLINK_ON_DONE)
            analogWrite(LED_PIN, 255 * int(led_brightness_level) / 100);
    }
    else
        return;
    lcd_lib_draw_string(5, 53, (char*)lcd_cache);
}
void lcd_draw_detail(char* pstr)
{
  static int detailStringIndex=0;
  static char* pstrBack=pstr;

  uint8_t detailStringLength=strlen(pstr);

  uint8_t yOffset = LS(56, 53, 53);

  if (detailStringLength<=20) {
    lcd_lib_draw_string_center(yOffset, pstr);
  }
  else{
    if (pstrBack!=pstr) {
      detailStringIndex=0;
      pstrBack=pstr;
    }
    lcd_lib_draw_string(-detailStringIndex, yOffset, pstr);
    detailStringIndex++;
    if (detailStringIndex>=6*detailStringLength) {
      detailStringIndex=-128;
    }
  }
}
void lcd_sd_menu_details_callback(uint8_t nr)
{
    if (nr == 0)
    {
        return;
    }
    for(uint8_t idx=0; idx<LCD_CACHE_COUNT; idx++)
    {
        if (LCD_CACHE_ID(idx) == nr)
        {
            if (LCD_CACHE_TYPE(idx) == 1)
            {
                lcd_lib_draw_string_centerP(53, PSTR("Folder"));
            }else{
                char buffer[64];
                if (LCD_DETAIL_CACHE_ID() != nr)
                {
                    card.getfilename(nr - 1);
                    if (card.errorCode())
                    {
                        card.clearError();
                        return;
                    }
                    LCD_DETAIL_CACHE_ID() = nr;
                    LCD_DETAIL_CACHE_TIME() = 0;
                    for(uint8_t e=0; e<EXTRUDERS; e++)
                        LCD_DETAIL_CACHE_MATERIAL(e) = 0;
                    card.openFile(card.filename, true);
                    if (card.isFileOpen())
                    {
                        for(uint8_t n=0;n<8;n++)
                        {
                            card.fgets(buffer, sizeof(buffer));
                            buffer[sizeof(buffer)-1] = '\0';
                            while (strlen(buffer) > 0 && buffer[strlen(buffer)-1] < ' ') buffer[strlen(buffer)-1] = '\0';
                            if (strncmp_P(buffer, PSTR(";TIME:"), 6) == 0)
                                LCD_DETAIL_CACHE_TIME() = atol(buffer + 6);
                            else if (strncmp_P(buffer, PSTR(";MATERIAL:"), 10) == 0)
                                LCD_DETAIL_CACHE_MATERIAL(0) = atol(buffer + 10);
#if EXTRUDERS > 1
                            else if (strncmp_P(buffer, PSTR(";MATERIAL2:"), 11) == 0)
                                LCD_DETAIL_CACHE_MATERIAL(1) = atol(buffer + 11);
#endif
                        }
                    }
                    if (card.errorCode())
                    {
                        //On a read error reset the file position and try to keep going. (not pretty, but these read errors are annoying as hell)
                        card.clearError();
                        LCD_DETAIL_CACHE_ID() = 255;
                    }
                }
                
                if (LCD_DETAIL_CACHE_TIME() > 0)
                {
                    char* c = buffer;
                    if (led_glow_dir)
                    {
                        strcpy_P(c, PSTR("Time: ")); c += 6;
                        c = int_to_time_string(LCD_DETAIL_CACHE_TIME(), c);
                    }else{
                        strcpy_P(c, PSTR("Material: ")); c += 10;
                        float length = float(LCD_DETAIL_CACHE_MATERIAL(0)) / (M_PI * (material[0].diameter / 2.0) * (material[0].diameter / 2.0));
                        if (length < 10000)
                            c = float_to_string(length / 1000.0, c, PSTR("m"));
                        else
                            c = int_to_string(length / 1000.0, c, PSTR("m"));
#if EXTRUDERS > 1
                        if (LCD_DETAIL_CACHE_MATERIAL(1))
                        {
                            *c++ = '/';
                            float length = float(LCD_DETAIL_CACHE_MATERIAL(1)) / (M_PI * (material[1].diameter / 2.0) * (material[1].diameter / 2.0));
                            if (length < 10000)
                                c = float_to_string(length / 1000.0, c, PSTR("m"));
                            else
                                c = int_to_string(length / 1000.0, c, PSTR("m"));
                        }
#endif
                    }
                    lcd_lib_draw_string(3, 53, buffer);
                }else{
                    lcd_lib_draw_stringP(3, 53, PSTR("No info available"));
                }
            }
        }
    }
}
void lcd_advance_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{

  if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos = -1;
  if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos = entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;

  uint8_t selIndex =constrain(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM, 0, entryCount-1);

  uint8_t drawOffset;

  lcd_lib_clear();

  switch (languageType) {
  case LANGUAGE_CHINESE:
  case LANGUAGE_KOREAN:
    drawOffset = (49-12*entryCount)/2+1;

    for(int8_t n=0; n<entryCount; n++)
    {

      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';
      if (n == selIndex)
      {
        lcd_lib_draw_string(4, drawOffset+12*n, CHINESE_POINT);
        lcd_lib_draw_string(16, drawOffset+12*n, ptr);
      }else{
        lcd_lib_draw_string(16, drawOffset+12*n, ptr);
      }
    }
    if (menuNameP != NULL) {
      lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-6, 127, 10 + 3);
      lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
    }
    lcd_lib_draw_hline(0, 127, 53 - 3);

    break;
  case LANGUAGE_ENGLISH:
    drawOffset = (40-10*entryCount)/2+13;
    for(int8_t n=0; n<entryCount; n++)
    {

      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';
      if (n == selIndex)
      {
        lcd_lib_draw_string(4, drawOffset+10*n, ENGLISH_POINT);
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }else{
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }
    }
    if (menuNameP != NULL) {
      lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-6, 127, 10);
      lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
    }
    lcd_lib_draw_hline(0, 127, 53);
    break;
  default:

    break;
  }




  entryDetailsCallback(selIndex);
}
void lcd_scroll_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{
  if (lcd_lib_button_pressed)
    return;    //Selection possibly changed the menu, so do not update it this cycle.

  if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos = 0;
  if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos = entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM - 1;

  uint8_t selIndex = uint16_t(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM);

  lcd_lib_clear();

  int16_t targetViewPos;
  int16_t viewDiff;
  int16_t drawOffset;
  uint8_t itemOffset;

  switch (languageType) {
  case LANGUAGE_CHINESE:
  case LANGUAGE_KOREAN:
  {
    static int16_t viewPos = 8 + 12;
    targetViewPos = selIndex * 12;
    viewDiff = targetViewPos - viewPos;

    if (viewDiff<0) {
      viewDiff += 18;
      if (viewDiff > 0) {
        viewDiff=0;
      }
    }
    else if (viewDiff>0) {
      viewDiff -= 18;
      if (viewDiff<0) {
        viewDiff=0;
      }
    }

    viewPos += viewDiff / 4;
    if (viewDiff > 0) { viewPos++; led_glow = led_glow_dir = 0; }
    if (viewDiff < 0) { viewPos--; led_glow = led_glow_dir = 0; }

    if (viewPos<0) {
      viewPos=0;
    }

    drawOffset = 7 + 12 -viewPos % 12;
    itemOffset = viewPos / 12;
    for(int8_t n=-2; n<4; n++)
    {
      uint8_t itemIdx = n + itemOffset;
      if (itemIdx >= entryCount)
        continue;

      char* ptr = entryNameCallback(itemIdx);
      ptr[20] = '\0';
      if (itemIdx == selIndex)
      {
        lcd_lib_draw_string(0, drawOffset+12*n, CHINESE_POINT);
        lcd_lib_draw_string(12, drawOffset+12*n, ptr);
      }else{
        lcd_lib_draw_string(12, drawOffset+12*n, ptr);
      }
    }
    lcd_lib_clear(0, 0, 127,0);

    lcd_lib_clear(0, 50, 127, 63);
    lcd_lib_clear(127-strlen_P(menuNameP)*6-6, 0, 127, 13);
    lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-6, 127, 13);

    lcd_lib_clear(0, 49, 127,49);
    lcd_lib_draw_hline(0, 127, 50);
    lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
  }
  break;

  case LANGUAGE_ENGLISH:
  {
    static int16_t viewPos = 8 +20;

    targetViewPos = selIndex * 10;
    viewDiff = targetViewPos - viewPos;

    if (viewDiff<0) {
      viewDiff += 15;
      if (viewDiff > 0) {
        viewDiff=0;
      }
    }
    else if (viewDiff>0) {
      viewDiff -= 15;
      if (viewDiff<0) {
        viewDiff=0;
      }
    }

    viewPos += viewDiff / 4;
    if (viewDiff > 0) { viewPos++; led_glow = led_glow_dir = 0; }
    if (viewDiff < 0) { viewPos--; led_glow = led_glow_dir = 0; }

    if (viewPos<0) {
      viewPos=0;
    }

    drawOffset = 8 +20 -viewPos % 10;
    itemOffset = viewPos / 10;
    for(int8_t n=-2; n<4; n++)
    {
      uint8_t itemIdx = n + itemOffset;
      if (itemIdx >= entryCount)
        continue;

      char* ptr = entryNameCallback(itemIdx);
      ptr[20] = '\0';
      if (itemIdx == selIndex)
      {
        lcd_lib_draw_string(0, drawOffset+10*n, ENGLISH_POINT);
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }else{
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }
    }

    lcd_lib_clear(0, 53, 127, 63);
    lcd_lib_clear(0, 0, 127, 9);
    lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-12, 127, 10);
    lcd_lib_draw_hline(0, 127, 53);
    lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
  }
  default:
    break;
  }

  entryDetailsCallback(selIndex);
}