Last active
November 10, 2022 17:12
-
-
Save kdorff/5c26fb21c573e4309da2587aa6e9b5d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// This is part of 4 files. Make sure you have the whole set | |
// tft-office.yaml https://gist.github.com/kdorff/363cc20a26fddf7a3dea6fabbcd04805 | |
// display-panel.h https://gist.github.com/kdorff/5c26fb21c573e4309da2587aa6e9b5d3 | |
// display-touch-panel.h https://gist.github.com/kdorff/78d45057ee7a1aaf92f839f576c99e0b | |
// tft-room-time-temp.h https://gist.github.com/kdorff/811f86b33bf8b63050dce7e91d70cac8 | |
// | |
#include "esphome.h" | |
#include <vector> | |
// A rectangular Panel to be displayed on the LCD that we can | |
// write one or more lines of centered text to. | |
class DisplayPanel { | |
public: | |
// Position of the panel | |
unsigned int x; | |
unsigned int y; | |
// Size of the panel | |
unsigned int w; | |
unsigned int h; | |
bool enabled = true; | |
// Reduction of font height when calculating positioning | |
// in printMulti(). | |
// If the lines are too far apart, increase this value. | |
int fontHeightOffset = 0; | |
// Change in vertical position when calculating | |
// positioning in printMiddle() or printMulti(). | |
// If the lines start too low in the panel, | |
// set this to a negative value. | |
int fontVertOffset = 0; | |
// Draw an outline around the panel | |
// using textColor | |
bool drawPanelOutline = false; | |
// Color of the panel | |
esphome::Color color; | |
// Color of the text printed to the panel | |
esphome::Color textColor; | |
// Font of the text printed to the panel | |
esphome::display::Font *font; | |
// Text lines to print on the panel. | |
std::vector<std::string> text = { }; | |
// Constructor | |
DisplayPanel(unsigned int _x, unsigned int _y, unsigned int _w, unsigned int _h) { | |
x = _x; | |
y = _y; | |
w = _w; | |
h = _h; | |
} | |
void draw(esphome::display::DisplayBuffer &display) { | |
drawRect(display); | |
drawText(display); | |
} | |
static void drawAllPanels(esphome::display::DisplayBuffer &display, std::vector<DisplayPanel> panels) { | |
for (std::vector<DisplayPanel>::iterator panel = panels.begin(); panel != panels.end(); panel++) { | |
(*panel).drawRect(display); | |
} | |
for (std::vector<DisplayPanel>::iterator panel = panels.begin(); panel != panels.end(); panel++) { | |
(*panel).drawText(display); | |
} | |
} | |
protected: | |
// Draw the Panel in the specified location | |
// at the specified color. | |
void drawRect(esphome::display::DisplayBuffer &display) { | |
if (!enabled || w == 0 || h == 0) { | |
// Noththing to draw. | |
return; | |
} | |
// ESP_LOGD("panel", "Drawing panel x=%d, y=%d, w=%d, h=%d", x, y, w, h); | |
display.filled_rectangle(x, y, w, h, color); | |
if (drawPanelOutline) { | |
display.rectangle(x, y, w, h, textColor); | |
} | |
} | |
void drawText(esphome::display::DisplayBuffer &display) { | |
if (!enabled || w == 0 || h == 0) { | |
// Noththing to draw. | |
return; | |
} | |
if (text.size() == 1) { | |
printMiddle(display, text[0].c_str()); | |
} | |
else if (text.size() > 1) { | |
printMulti(display, text); | |
} | |
} | |
// Print centered text with padding from the top. | |
// Useful if printing multiple lines of text within a Panel. | |
void printMulti(esphome::display::DisplayBuffer &display, | |
std::vector<std::string> &text) { | |
// Determine the height of a line | |
int width, x_offset, textHeight, height; | |
font->measure("M", &width, &x_offset, &textHeight, &height); | |
textHeight += fontHeightOffset; | |
int topPadding = (h - (text.size() * (textHeight))) / 2; | |
topPadding = topPadding >= 0 ? topPadding : 0; | |
int lineNum = 0; | |
for (std::vector<std::string>::iterator t = text.begin(); t != text.end(); t++) { | |
std::string text = *t; | |
int printY = y + topPadding + (lineNum * textHeight); | |
display.print( | |
x + ((int) (w/2)), | |
y + topPadding + (lineNum * textHeight) + fontVertOffset, | |
font, textColor, TextAlign::TOP_CENTER, text.c_str()); | |
lineNum++; | |
} | |
} | |
// Print text in the middle of the panel. | |
// Useful if printing a single line of text within a Panel. | |
void printMiddle(esphome::display::DisplayBuffer &display, | |
const char *text) { | |
display.print( | |
x + ((int) (w/2)), | |
y + ((int) (h/2) + fontVertOffset), | |
font, textColor, TextAlign::CENTER, text); | |
} | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment