Trying to create an associative array of pages and buttons to display on ESP32

I’m playing around with a Sunton 2.8" touch LCD board powered by an ESP32 and trying to create a grid of buttons that toggle lights and things in Home Assistant. I’m hoping to define an array of all the buttons I want to show, indexed by page. I want to have a special button that changes pages, but not literal ESPHome Display Pages, but rather a variable holding the current page name or #. When the page name/# is var changed, I want to grab the page-specific button names from the array and display them to the user.

Here’s what I have so far, using a single page of hard-coded buttons. I’m not sure how to define my array of buttons, nor how I would reference it in the display component. Probably even more tricky is how I would go about making the binary_sensors for each button… maybe I would need to keep a single hardcoded set of those but pass data with the button name when they are activated?

Any help is super appreciated!

substitutions:
  device_name: esp-test
  friendly_name: Test ESP Remote

esphome:
  name: $device_name
  friendly_name: $friendly_name
 
esp32:
  board: esp32dev
  framework:
    type: arduino

logger:

api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  ap:
    ssid: "Test ESP Fallback Hotspot"
    password: "1234567890"

captive_portal:

web_server:
  port: 80

font:
  - file: 'fonts/Arimo-Regular.ttf'
    id: arimo24
    size: 24

color:
  - id: ha_blue
    hex: 51c0f2

light:
  - platform: monochromatic
    output: backlight_pwm
    name: Display Backlight
    id: backlight
    restore_mode: ALWAYS_ON

spi:
  - id: tft
    clk_pin: GPIO14
    mosi_pin: GPIO13
    miso_pin: GPIO12
  - id: touch
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

output:
  - platform: ledc
    pin: GPIO21
    id: backlight_pwm

touchscreen:
  platform: xpt2046
  spi_id: touch
  cs_pin: GPIO33
  interrupt_pin: GPIO36
  update_interval: 50ms
  report_interval: 1s
  threshold: 400
  calibration_x_min: 3860
  calibration_x_max: 280
  calibration_y_min: 340
  calibration_y_max: 3860
  swap_x_y: false      

time:
  - platform: homeassistant
    id: esptime

globals:
  - id: btn_width
    type: int
    restore_value: no
    initial_value: '115'
  - id: btn_height
    type: int
    restore_value: no
    initial_value: '55'
  - id: btn_col1
    type: int
    restore_value: no
    initial_value: '10'
  - id: btn_col2
    type: int
    restore_value: no
    initial_value: '135'
  - id: btn_col3
    type: int
    restore_value: no
    initial_value: '260'
  - id: btn_row1
    type: int
    restore_value: no
    initial_value: '45'
  - id: btn_row2
    type: int
    restore_value: no
    initial_value: '110'
  - id: btn_row3
    type: int
    restore_value: no
    initial_value: '175'

binary_sensor:
  - platform: touchscreen
    name: Btn PG
    id: btn_pg
    x_min: 260
    x_max: 310
    y_min: 45
    y_max: 230
#    on_press:
#       ... change pages ....

  - platform: touchscreen
    name: Btn Row1 Col1
    id: btn_row1_col1
    x_min: 10
    x_max: 125
    y_min: 45
    y_max: 100

  - platform: touchscreen
    name: Btn Row1 Col2
    id: btn_row1_col2
    x_min: 135
    x_max: 250
    y_min: 45
    y_max: 100

  - platform: touchscreen
    name: Btn Row2 Col1
    id: btn_row2_col1
    x_min: 10
    x_max: 125
    y_min: 110
    y_max: 165

  - platform: touchscreen
    name: Btn Row2 Col2
    id: btn_row2_col2
    x_min: 135
    x_max: 250
    y_min: 110
    y_max: 165

  - platform: touchscreen
    name: Btn Row3 Col1
    id: btn_row3_col1
    x_min: 10
    x_max: 125
    y_min: 175
    y_max: 230

  - platform: touchscreen
    name: Btn Row3 Col2
    id: btn_row3_col2
    x_min: 135
    x_max: 250
    y_min: 175
    y_max: 230

display:
  - id: my_display
    platform: ili9xxx
    model: ili9341
    spi_id: tft
    cs_pin: GPIO15
    dc_pin: GPIO2
    rotation: 90
    lambda: |-              
      it.fill(id(Color::BLACK));
      
      it.strftime(155, 23, id(arimo24), TextAlign::CENTER, "%Y-%m-%d %H:%M", id(esptime).now());

      it.filled_rectangle(id(btn_col3), id(btn_row1), 50, 185, id(ha_blue));
      it.print(id(btn_col3) + 50 / 2, id(btn_row1) + 185 / 2, id(arimo24), TextAlign::CENTER, "PG");

      // row 1
      it.filled_rectangle(id(btn_col1), id(btn_row1), id(btn_width), id(btn_height), id(ha_blue));
      it.print(id(btn_col1) + id(btn_width) / 2, id(btn_row1) + id(btn_height) / 2, id(arimo24), TextAlign::CENTER, "Vol +");

      it.filled_rectangle(id(btn_col2), id(btn_row1), id(btn_width), id(btn_height), id(ha_blue));
      it.print(id(btn_col2) + id(btn_width) / 2, id(btn_row1) + id(btn_height) / 2, id(arimo24), TextAlign::CENTER, "Vol -");
      
      // row 2
      it.filled_rectangle(id(btn_col1), id(btn_row2), id(btn_width), id(btn_height), id(ha_blue));
      it.print(id(btn_col1) + id(btn_width) / 2, id(btn_row2) + id(btn_height) / 2, id(arimo24), TextAlign::CENTER, "Lamp +");

      it.filled_rectangle(id(btn_col2), id(btn_row2), id(btn_width), id(btn_height), id(ha_blue));
      it.print(id(btn_col2) + id(btn_width) / 2, id(btn_row2) + id(btn_height) / 2, id(arimo24), TextAlign::CENTER, "Lamp -");
      
      // row 3
      it.filled_rectangle(id(btn_col1), id(btn_row3), id(btn_width), id(btn_height), id(ha_blue));
      it.print(id(btn_col1) + id(btn_width) / 2, id(btn_row3) + id(btn_height) / 2, id(arimo24), TextAlign::CENTER, "Test +");

      it.filled_rectangle(id(btn_col2), id(btn_row3), id(btn_width), id(btn_height), id(ha_blue));
      it.print(id(btn_col2) + id(btn_width) / 2, id(btn_row3) + id(btn_height) / 2, id(arimo24), TextAlign::CENTER, "Test -");
          

Following-up… I gave up on this and now that LVGL is supported by ESPHome I used that instead.