Best LCD Menu Library ?

I just wrote my own for my wheelieometer, basically in Setup if the button is held down it goes into a setup mode and prompts the user to release the button. It then prompts for each parameter in turn; for each pressing the button increments the value by one (there is a debounce, so holding the button increments the value slowly), the value reverts to its minimum if the maximum is exceeded. If the button isn't pressed for a specified period, the value is accepted and the user is prompted for the next value.

Example (could do with using more generic functions!):

if (!digitalRead(PinDisplayButton)) //Read button directly as we don't need debounce
  {
    //Button Pressed, enter setup mode
    oled.print(F("Setup Mode"));
    oled.clearToEOL();
    oled.setCursor(0,4);
    oled.print(F("Release"));
    oled.clearToEOL();
    oled.setCursor(0,6);
    oled.print(F("Button!"));
    oled.clearToEOL();

    //Wait for button to be released
    do
    {
    } while (!digitalRead(PinDisplayButton));
    OldDisplayButtonTime = millis(); //Reset time of last button press
    
    if(ClockAvailable)
    {
      byte RTCDataMax[6]; //Array to hold maximum value of each element of the date and time
      RTCDataMax[0] = 59; //Maximum seconds
      RTCDataMax[1] = 59; //Maximum minute
      RTCDataMax[2] = 23; //Maximum hour
      RTCDataMax[3] = 31; //Maximum date (no check made for shorter months)
      RTCDataMax[4] = 12; //Maximum month
      RTCDataMax[5] = 99; //Maximum year
  
      byte RTCDataMin[6]; //Array to hold minimum value of each element of the date and time
      RTCDataMin[0] = 0; //Minimum seconds
      RTCDataMin[1] = 0; //Minimum minute
      RTCDataMin[2] = 0; //Minimum hour
      RTCDataMin[3] = 1; //Minimum date
      RTCDataMin[4] = 1; //Minimum month
      RTCDataMin[5] = 0; //Minimum year
      
      byte RtcData[6]; //Array to save clock values
      
      //Print fixed text to screen
      oled.setCursor(0,2);
      oled.print(F("Set Clock"));
      oled.clearToEOL();
      oled.setCursor(0,4);
      oled.print(F("Set"));
      oled.clearToEOL();
      oled.setCursor(0,6);
      oled.clearToEOL();      

      //Retrieve current time
      HCRTC.RTCRead(I2CDS1307Add); 
      RtcData[0] = HCRTC.GetSecond(); //Seconds
      RtcData[1] = HCRTC.GetMinute(); //Minutes
      RtcData[2] = HCRTC.GetHour(); //Hours
      RtcData[3] = HCRTC.GetDay(); //Date
      RtcData[4] = HCRTC.GetMonth(); //Month
      RtcData[5] = HCRTC.GetYear(); //Year 
      
      //Loop over elements of date and time
      for (byte ClockElement = 5;  ClockElement < 6; ClockElement--) //After 0 value will overload to 255 hence the end condition
      {
        //State what is being set
        oled.setCursor(49,4); //Position to write
        switch (ClockElement)
        {
          case 5:
            oled.print(F("Year"));
            break;
          case 4:
            oled.print(F("Month"));
            break;
          case 3:
            oled.print(F("Date"));
            break;
          case 2:
            oled.print(F("Hour"));
            break;
          case 1:
            oled.print(F("Minute"));
            break;     
          case 0:
            oled.print(F("Second"));
            break;                            
        }
        oled.clearToEOL();
  
        //Print current value to screen
        oled.setCursor(0,6);
        oled.print(RtcData[ClockElement]);
        oled.clearToEOL();
  
        //Wait for button presses to change value
        do
        {
          if (CheckDisplayButton())
          {
            //Button pressed: increment value
            RtcData[ClockElement]++;
            if(RtcData[ClockElement] > RTCDataMax[ClockElement]) //Jump to minimum value
            {
              RtcData[ClockElement] = RTCDataMin[ClockElement];
            }
            //Update display
            oled.setCursor(0,6);
            oled.print(RtcData[ClockElement]);
            oled.clearToEOL();
          } 
         } while (!IntervalCheck(OldDisplayButtonTime, SetupTimeout)); //After timeout, proceed 
        OldDisplayButtonTime = millis(); //Reset timeout for next element
      }
      
      HCRTC.RTCWrite(I2CDS1307Add, RtcData[5], RtcData[4], RtcData[3], RtcData[2], RtcData[1], RtcData[0], 1);  //Set Clock, last parameter is weekday and not used
      delay(100); //Delay to let the clock be set
    }

    //Minimum angle to trigger a wheelie
    oled.setCursor(0,2);
    oled.print(F("Set Angle"));
    oled.clearToEOL();
    oled.setCursor(0,4);
    oled.print(F("Threshold"));
    oled.clearToEOL();

    //Read current angle from non-volatile EEPROM memory
    MinAngle = EEPROM.read(MinAngleEEPROMAddress);

    //Check MinAngle in range, if not default to smallest
    if((MinAngle < MinAngleMin) || (MinAngle > MinAngleMax))
    {
      MinAngle = MinAngleMin;
    }

    //Write current value to screen
    oled.setCursor(0,6);
    oled.clearToEOL();
    oled.setCursor(25,6);
    oled.set1X();
    oled.print(F("o"));
    oled.set2X();
    oled.setCursor(0,6);
    oled.print(MinAngle,0);

    //Wait for button presses to change value
    do
    {
      if (CheckDisplayButton())
      {
        //Button pressed: increment value by 5 degrees
        MinAngle += 5;
        if(MinAngle > MinAngleMax) //Jump to minimum value
        {
          MinAngle = MinAngleMin;
        }
        //Update display
        oled.setCursor(0,6);
        oled.print(F("  "));
        oled.setCursor(0,6);
        oled.print(MinAngle,0);
      } 
    } while (!IntervalCheck(OldDisplayButtonTime, SetupTimeout)); //After timeout, proceed 
    OldDisplayButtonTime = millis(); //Reset timeout for next element

    EEPROM.update(MinAngleEEPROMAddress, (int)MinAngle); //Update stored value