[Resolved] Array must be initialized with a brace-enclosed initializer

static inline uint16_t Color_To_565(uint8_t r, uint8_t g, uint8_t b){
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}

typedef struct{
  char text[12];
  uint16_t color;
}Button;

static const char ref[] PROGMEM = "References";
static const char ren[] PROGMEM = "Rename";
static const char gs[] PROGMEM = "Get/Set...";
static const char nc[] PROGMEM = "New Class";
static const char exm[] PROGMEM = "Ext. Meth.";
static const char tstr[] PROGMEM = "ToString...";
static const char inl[] PROGMEM = "InLine";
static const char rtst[] PROGMEM = "Runt Test";
static const char none[] PROGMEM = "?";

#define BUT_REF       { ref,   Color_To_565(255, 190, 98 ) }
#define BUT_REN       { ren,   Color_To_565(255, 190, 98 ) } 
#define BUT_GETSET    { gs,    Color_To_565(64 , 219, 187) } 
#define BUT_NEWCLASS  { nc,    Color_To_565(64 , 219, 187) } 
#define BUT_EXTMETH   { exm,   Color_To_565(106, 175, 255) } 
#define BUT_TOSTR     { tstr,  Color_To_565(64 , 219, 187) } 
#define BUT_INLINE    { inl,   Color_To_565(106, 175, 255) } 
#define BUT_RUNTEST   { rtst,  Color_To_565(255, 104, 129) }
#define BUT_NONE      { none,  0x0000                      } 

#define BUTS  { BUT_REF, BUT_REN, BUT_GETSET, BUT_NEWCLASS, BUT_EXTMETH },{ BUT_TOSTR, BUT_INLINE, BUT_RUNTEST, BUT_NONE, BUT_NONE }

static const Button buttons[NB_COL][NB_ROW] PROGMEM = { BUTS };

This gives me:
‘array must be initialized with a brace-enclosed initializer’
on the

static const Button buttons[NB_COL][NB_ROW] PROGMEM = { BUTS };

I don’t understand why ?!

I think Color_To_565() is not a constant (even though it's an inline function), so it can't be used to initialize a global static variable. Try defining it as another macro, instead.

Is the code you posted the same as you are trying to compile, I get a completely different error, which is caused by Button.text being declared as a char array instead of a const char*

#define Color_To_565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | (((b) & 0xF8) >> 3))

typedef struct{
  char* text;
  uint16_t color;
}Button;

static const char ref[] PROGMEM = "References";
static const char ren[] PROGMEM = "Rename";
static const char gs[] PROGMEM = "Get/Set...";
static const char nc[] PROGMEM = "New Class";
static const char exm[] PROGMEM = "Ext. Meth.";
static const char tstr[] PROGMEM = "ToString...";
static const char inl[] PROGMEM = "InLine";
static const char rtst[] PROGMEM = "Runt Test";
static const char none[] PROGMEM = "?";

#define BUT_REF       { ref,   Color_To_565(255, 190, 98 ) }
#define BUT_REN       { ren,   Color_To_565(255, 190, 98 ) }
#define BUT_GETSET    { gs,    Color_To_565(64 , 219, 187) }
#define BUT_NEWCLASS  { nc,    Color_To_565(64 , 219, 187) }
#define BUT_EXTMETH   { exm,   Color_To_565(106, 175, 255) }
#define BUT_TOSTR     { tstr,  Color_To_565(64 , 219, 187) }
#define BUT_INLINE    { inl,   Color_To_565(106, 175, 255) }
#define BUT_RUNTEST   { rtst,  Color_To_565(255, 104, 129) }
#define BUT_NONE      { none,  0x0000                      }

#define BUTS  { BUT_REF, BUT_REN, BUT_GETSET, BUT_NEWCLASS, BUT_EXTMETH },{ BUT_TOSTR, BUT_INLINE, BUT_RUNTEST, BUT_NONE, BUT_NONE }

#define NB_COL 2
#define NB_ROW 5

static const Button buttons[NB_COL][NB_ROW] PROGMEM = { BUTS };

I’ve corrected:

typedef struct{
  const char text[12];
  uint16_t color;
}Button;

After some tests, i’ve found that it’s the line

static const char rtst[] PROGMEM = "Runt Test";

That seems to cause the problem.

I’ve finally replace the color function with hex value.
Created each button in a variable in PROGMEM (with direct String creation)

static const Button but_ref PROGMEM = { "References", 0xFDEC};
static const Button but_ren PROGMEM = { "Rename",   0xFDEC}; 
...

added these to the final array:

static const Button buttons[NB_COL][NB_ROW] PROGMEM =  { { but_ref,...},{but_ren,...}  } ;

It’s finally working.

Thanks.

There’s no need to use macros here, just make the Color_To_565 function constexpr. I also added a default constructor for your struct so you don’t have to repeat the “none” button initialization in the array.

constexpr uint16_t Color_To_565(uint8_t r, uint8_t g, uint8_t b){
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}

static const char ref[] PROGMEM = "References";
static const char ren[] PROGMEM = "Rename";
static const char gs[] PROGMEM = "Get/Set...";
static const char nc[] PROGMEM = "New Class";
static const char exm[] PROGMEM = "Ext. Meth.";
static const char tstr[] PROGMEM = "ToString...";
static const char inl[] PROGMEM = "InLine";
static const char rtst[] PROGMEM = "Runt Test";
static const char none[] PROGMEM = "?";

struct Button {
  constexpr Button(const char *text, uint16_t color)
   : text(text), color(color) {}
  constexpr Button() : text(none), color(0x0000) {}
  
  const char *text;
  uint16_t color;
};

const Button buttons[][5] PROGMEM = {
  {
    { ref,  Color_To_565(255, 190, 98 ) },
    { ren,  Color_To_565(255, 190, 98 ) },
    { gs,   Color_To_565(64 , 219, 187) },
    { nc,   Color_To_565(64 , 219, 187) },
    { exm,  Color_To_565(106, 175, 255) },
  },
  {
    { tstr, Color_To_565(64 , 219, 187) },
    { inl,  Color_To_565(106, 175, 255) },
    { rtst, Color_To_565(255, 104, 129) },
  },
};

void setup() {
  Serial.begin(115200);
  while (!Serial);
  for (const auto &row : buttons) {
    for (const auto &button_P : row) {
      Button button; // button in RAM
      memcpy_P(&button, &button_P, sizeof(button)); // copy from Flash to RAM
      Serial.println(reinterpret_cast<const __FlashStringHelper *>(button.text));
    }
    Serial.println();
  }
}

void loop() {}

Pieter