Centering text when using multiple printf

Hi,

I thought I would post my solution here for others facing this:

  • Create a header file (“e.g. text_utils.h”) which you include in the esp yaml file.
  • In this header, define several overloads of the same function to calculate the width given different types: i.e. string, int, float, and time.
  • Then, in all lambda calls, invoke GetTextWidth without worrying about the type and it will be resolved accordingly
int GetTextBounds(esphome::display::Display* it, esphome::font::Font *font, const char *buffer)
{
    int x1 = 0;     // A pointer to store the returned x coordinate of the upper left corner in. 
    int y1 = 0;     // A pointer to store the returned y coordinate of the upper left corner in.
    int width = 0;  // A pointer to store the returned text width in.
    int height = 0; // A pointer to store the returned text height in. 
    it->get_text_bounds(0, 0, buffer, font, TextAlign::TOP_LEFT, &x1, &y1, &width, &height);
    return width;
}

int GetTextWidth(esphome::display::Display* it, esphome::font::Font *font, const char* formatting, const char *raw_text){
    char temp_buffer[80];
    sprintf(temp_buffer, formatting, raw_text);
    return GetTextBounds(it, font, temp_buffer);
}
...  // overloads for int and float
// Calculate the width of time format
int GetTextWidth(esphome::display::Display* it, esphome::font::Font *font, const char* formatting, esphome::ESPTime time){
    auto c_tm = time.to_c_tm();
    size_t buffer_length = 80;
    char temp_buffer[buffer_length];
    strftime(temp_buffer, buffer_length, formatting, &c_tm);
    return GetTextBounds(it, font, temp_buffer);
}

Using it within lambda is quite trivial:

      // Estimating total length of text
      int day_size = GetTextWidth(&it, id(day_font), "%d", id(hass_time).now());
      int icon_size = GetTextWidth(&it, id(font_mdi_large), "%s", weather_icon_map[id(condition_now).state.c_str()].c_str());
      int temperature_size = GetTextWidth(&it, id(temperature_font), "%s°C", id(temperature_now).state.c_str());
6 Likes