olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
5.07k stars 1.05k forks source link

How to scroll down/up a menu ? #2392

Closed eagl1 closed 6 months ago

eagl1 commented 7 months ago

Hi,

I'm working on developing a menu and I reached the part where I want to scroll down/up the menu but I don't know how.

This is the function I'm working on:

// constants ////////////////////////////////////////////////
// # lists settings

#define   LIST_COUNT            8
#define   LIST_PER_FRAME        5

#define   LIST_Y_START_POINT    1
#define   LIST_X_START_POINT    2
#define   LIST_Y(_Y)            (LIST_Y_START_POINT+(12*_Y))

// # selection settings
#define   SELECT_WIDTH          65
#define   SELECT_HEIGHT         11
#define   SELECT_X_START_POINT  0
#define   SELECT_Y_START_POINT  0
#define   SELECT_Y(_Y)          (SELECT_Y_START_POINT+(12*_Y))

// variables ////////////////////////////////////////////////
uint8_t select_ptr = 0;
//uint8_t list_y = LIST_Y(0);

struct example_list{
  uint8_t y_position;
  const char* list_name;
};

example_list list1[] = {
  {LIST_Y(0), "SETTING 1"},
  {LIST_Y(1), "SETTING 2"},
  {LIST_Y(2), "SETTING 3"},
  {LIST_Y(3), "SETTING 4"},  
  {LIST_Y(4), "SETTING 5"},
  {LIST_Y(5), "SETTING 6"},
  {LIST_Y(6), "SETTING 7"},
  {LIST_Y(7), "SETTING 8"}, 
};

U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);

void u8g2_prepare(void) {
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void glcd_initialize(void) {
  u8g2.begin(); 
  u8g2_prepare();
}

void glcd_print_list(void){

  u8g2.firstPage();
  do {

    // draw list
    u8g2.setDrawColor(1);
    for(int i = 0; i < LIST_COUNT; i++){
      u8g2.drawStr(LIST_X_START_POINT, list1[i].y_position, list1[i].list_name);
    }

    // selected list
    u8g2.setDrawColor(1);
    u8g2.drawBox(SELECT_X_START_POINT, SELECT_Y(select_ptr), SELECT_WIDTH, SELECT_HEIGHT);
    u8g2.setDrawColor(0);
    u8g2.drawStr(LIST_X_START_POINT, list1[select_ptr].y_position, list1[select_ptr].list_name);

    if(select_ptr > 5){
      // u8g2.drawRFrame(u8g2,,,,); // <---------- I'm here
    }

  } while (u8g2.nextPage());   
}

As select_ptr will be modified by push button read function.

olikraus commented 6 months ago

Scrollings means to redraw something after a short time with a small offset: https://github.com/olikraus/u8g2/blob/master/sys/arduino/u8g2_page_buffer/IconMenu/IconMenu.ino

eagl1 commented 6 months ago

Yep, I wanted vertical scroll menu type.

I was working on it and did this:

#include <U8g2lib.h>

// variables ////////////////////////////////////////////////
int8_t select_ptr = 0;
int8_t name_ptr = 0;
int8_t list_ptr = 0;
bool list_limi_lock = 0;
bool glcd_update = 0; // on button event, sensor read event ... etc.
//uint8_t list_y = LIST_Y(0);

struct example_list{
  const char* list_name;
};

const char* list1[] = {
"SETTING 1", "SETTING 2", "SETTING 3", "SETTING 4", "SETTING 5", "SETTING 6", "SETTING 7", "SETTING 8"
};

// constants ////////////////////////////////////////////////
// # lists settings
#define   LIST_COUNT            (sizeof(list_name)/sizeof(list_name[0]))
#define   LIST_PER_FRAME        5

#define   LIST_Y_START_POINT    1
#define   LIST_X_START_POINT    2
#define   LIST_Y(_Y)            (LIST_Y_START_POINT+(12*_Y))

// # selection box settings
#define   SELECT_WIDTH          65
#define   SELECT_HEIGHT         11
#define   SELECT_X_START_POINT  0
#define   SELECT_Y_START_POINT  0
#define   SELECT_Y(_Y)          (SELECT_Y_START_POINT+(12*_Y))

U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, /* CS=*/ 10, /* reset=*/ 8);

void u8g2_prepare(void) {
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}

void glcd_initialize(void) {
  u8g2.begin(); 
  u8g2_prepare();
}

void glcd_print_list(void){

  if(!button_lock && !glcd_update){
    u8g2.firstPage();
    do {

      u8g2.clearBuffer();

      // draw full list
      u8g2.setDrawColor(1);
      for(int i = 0, j = list_ptr; i < LIST_PER_FRAME; j++, i++){
        u8g2.drawStr(LIST_X_START_POINT, LIST_Y(i), list1[j].list_name);
      }

      // draw selected list with selection box
      u8g2.setDrawColor(1);
      u8g2.drawBox(SELECT_X_START_POINT, SELECT_Y(select_ptr), SELECT_WIDTH, SELECT_HEIGHT);
      u8g2.setDrawColor(0);
      u8g2.drawStr(LIST_X_START_POINT, LIST_Y(select_ptr), list1[name_ptr].list_name);

      glcd_update = 1;
    } while (u8g2.nextPage());  
  } 
}

void glcd_update_button_control(void){
    if (lcd_button_index && button_execution == true) {

      switch(lcd_button_index){
        case BUTTON_UP:
          select_ptr--;
          name_ptr--;
          if(select_ptr < 0){ select_ptr = 0; list_ptr--; }
          if(name_ptr < 1){ name_ptr = 0;}
          if(list_ptr < 1){ list_ptr = 0;}
        break;

        case BUTTON_DOWN:
          select_ptr++;
          name_ptr++;
          if(select_ptr > 4){ select_ptr = 4; list_ptr++; }
          if(name_ptr > LIST_COUNT - 1){ name_ptr = LIST_COUNT - 1; }
          if(list_ptr > LIST_COUNT - LIST_PER_FRAME){ list_ptr = LIST_COUNT - LIST_PER_FRAME; }
        break;

        case BUTTON_SET:

        break;

        case BUTTON_BACK:

        break;

      }
      lcd_button_index = NOT_SELECTED;
      button_execution = false;
      glcd_update = 0;
    }
}

const char *convert_number(uint16_t number) {
  static char buf[3];
  strcpy(buf, u8g2_u8toa(number, 2));
  return buf;
}

const char *print_logic_state(bool number) {
  static char buf[3];
  strcpy(buf, u8g2_u8toa(number, 1));
  return buf;
}

const char *print_motor_speed(uint16_t number) {
  static char buf[3];
  strcpy(buf, u8g2_u8toa(number, 3));
  return buf;
}

It's working now.

Thanks for the wonderful library.