diff --git a/Extensions/Button.cpp b/Extensions/Button.cpp index 321b477..38b817e 100644 --- a/Extensions/Button.cpp +++ b/Extensions/Button.cpp @@ -27,15 +27,26 @@ void TFT_eSPI_Button::initButtonUL( _y1 = y1; _w = w; _h = h; + _xd = 0; + _yd = 0; _outlinecolor = outline; _fillcolor = fill; _textcolor = textcolor; _textsize = textsize; + _textdatum = MC_DATUM; _gfx = gfx; strncpy(_label, label, 9); } -void TFT_eSPI_Button::drawButton(bool inverted) { +// Adjust text datum and x, y deltas +void TFT_eSPI_Button::setLabelDatum(int16_t x_delta, int16_t y_delta, uint8_t datum) +{ + _xd = x_delta; + _yd = y_delta; + _textdatum = datum; +} + +void TFT_eSPI_Button::drawButton(bool inverted, String long_name) { uint16_t fill, outline, text; if(!inverted) { @@ -56,13 +67,18 @@ void TFT_eSPI_Button::drawButton(bool inverted) { _gfx->setTextSize(_textsize); uint8_t tempdatum = _gfx->getTextDatum(); - _gfx->setTextDatum(MC_DATUM); - _gfx->drawString(_label, _x1 + (_w/2), _y1 + (_h/2) -4); + _gfx->setTextDatum(_textdatum); + if (long_name == "") + //_gfx->drawString(_label, _x1 + (_w/2), _y1 + (_h/2) -4); + _gfx->drawString(_label, _x1 + _xd, _y1 + (_h/2) + _yd); + else + _gfx->drawString(long_name, _x1 + _xd, _y1 + (_h/2) + _yd); _gfx->setTextDatum(tempdatum); } // Some added arguments for more custom buttons // Mod author: https://github.com/justcallmekoko +/* void TFT_eSPI_Button::drawButton(uint8_t d, int padding, String button_name, boolean inverted) { uint16_t fill, outline, text; @@ -92,7 +108,7 @@ void TFT_eSPI_Button::drawButton(uint8_t d, int padding, String button_name, boo else _gfx->drawString(button_name, _x1 + padding, _y1 + (_h/2)); _gfx->setTextDatum(tempdatum); -} +}*/ bool TFT_eSPI_Button::contains(int16_t x, int16_t y) { return ((x >= _x1) && (x < (_x1 + _w)) && diff --git a/Extensions/Button.h b/Extensions/Button.h index 77a6271..f8ca317 100644 --- a/Extensions/Button.h +++ b/Extensions/Button.h @@ -18,8 +18,12 @@ class TFT_eSPI_Button { void initButtonUL(TFT_eSPI *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h, uint16_t outline, uint16_t fill, uint16_t textcolor, char *label, uint8_t textsize); - void drawButton(bool inverted = false); - void drawButton(uint8_t d = ML_DATUM, int padding = 0, String button_name = "", boolean inverted = false); + + // Adjust text datum and x, y deltas + void setLabelDatum(int16_t x_delta, int16_t y_delta, uint8_t datum = MC_DATUM); + + void drawButton(bool inverted = false, String long_name = ""); + //void drawButton(uint8_t d = ML_DATUM, int padding = 0, String button_name = "", boolean inverted = false); bool contains(int16_t x, int16_t y); void press(bool p); @@ -29,9 +33,9 @@ class TFT_eSPI_Button { private: TFT_eSPI *_gfx; - int16_t _x1, _y1; // Coordinates of top-left corner + int16_t _x1, _y1, _xd, _yd; // Coordinates of top-left corner uint16_t _w, _h; - uint8_t _textsize; + uint8_t _textsize, _textdatum; uint16_t _outlinecolor, _fillcolor, _textcolor; char _label[10]; diff --git a/User_Setup.h b/User_Setup.h index 5ac2669..829b1dc 100644 --- a/User_Setup.h +++ b/User_Setup.h @@ -129,9 +129,9 @@ // ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ###### // For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation -#define TFT_CS PIN_D8 // Chip select control pin D8 -#define TFT_DC PIN_D3 // Data Command control pin -#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line) +//#define TFT_CS PIN_D8 // Chip select control pin D8 +//#define TFT_DC PIN_D3 // Data Command control pin +//#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line) //#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V //#define TFT_BL PIN_D1 // LED back-light (only for ST7789 with backlight control pin) @@ -164,17 +164,17 @@ // For ESP32 Dev board (only tested with ILI9341 display) // The hardware SPI can be mapped to any pins -//#define TFT_MISO 19 -//#define TFT_MOSI 23 -//#define TFT_SCLK 18 -//#define TFT_CS 15 // Chip select control pin -//#define TFT_DC 2 // Data Command control pin -//#define TFT_RST 4 // Reset pin (could connect to RST pin) +#define TFT_MISO 19 // Matching T_DO +#define TFT_MOSI 23 // Matching T_DIN +#define TFT_SCLK 18 // Matching T_CLK +#define TFT_CS 17 // Chip select control pin +#define TFT_DC 16 // Data Command control pin +#define TFT_RST 5 // Reset pin (could connect to RST pin) //#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST -//#define TFT_BL 32 // LED back-light (only for ST7789 with backlight control pin) +#define TFT_BL 32 // LED back-light (only for ST7789 with backlight control pin) -//#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen +#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen //#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only diff --git a/examples/Generic/TFT_Button_Label_Datum/TFT_Button_Label_Datum.ino b/examples/Generic/TFT_Button_Label_Datum/TFT_Button_Label_Datum.ino new file mode 100644 index 0000000..55f62fe --- /dev/null +++ b/examples/Generic/TFT_Button_Label_Datum/TFT_Button_Label_Datum.ino @@ -0,0 +1,192 @@ +/* + The TFT_eSPI library incorporates an Adafruit_GFX compatible + button handling class. + + This example displays a column of buttons with varying label + alignments. + + The sketch has been tested on the ESP32 (which supports SPIFFS) + + Adjust the definitions below according to your screen size +*/ + +#include "FS.h" + +#include + +#include + +TFT_eSPI tft = TFT_eSPI(); + +// This is the file name used to store the calibration data +// You can change this to create new calibration files. +// The SPIFFS file name must start with "/". +#define CALIBRATION_FILE "/TouchCalData1" + +// Set REPEAT_CAL to true instead of false to run calibration +// again, otherwise it will only be done once. +// Repeat calibration if you change the screen rotation. +#define REPEAT_CAL false + +// Keypad start position, key sizes and spacing +#define KEY_X 160 // Centre of key +#define KEY_Y 50 +#define KEY_W 320 // Width and height +#define KEY_H 22 +#define KEY_SPACING_X 0 // X and Y gap +#define KEY_SPACING_Y 1 +#define KEY_TEXTSIZE 1 // Font size multiplier +#define BUTTON_X_DELTA 22 +#define NUM_KEYS 6 + +TFT_eSPI_Button key[NUM_KEYS]; + +void setup() { + + Serial.begin(115200); + + tft.init(); + + // Set the rotation before we calibrate + tft.setRotation(1); + + // Check for backlight pin if not connected to VCC + #ifndef TFT_BL + Serial.println("No TFT backlight pin defined"); + #else + pinMode(TFT_BL, OUTPUT); + digitalWrite(TFT_BL, HIGH); + #endif + + // call screen calibration + touch_calibrate(); + + // Clear screen + tft.fillScreen(TFT_BLACK); + + tft.setFreeFont(&FreeMono9pt7b); + + drawButtons(); +} + +void loop() { + uint16_t t_x = 0, t_y = 0; // To store the touch coordinates + + // Get current touch state and coordinates + boolean pressed = tft.getTouch(&t_x, &t_y); + + // Adjust press state of each key appropriately + for (uint8_t b = 0; b < NUM_KEYS; b++) { + if (pressed && key[b].contains(t_x, t_y)) + key[b].press(true); // tell the button it is pressed + else + key[b].press(false); // tell the button it is NOT pressed + } + + // Check if any key has changed state + for (uint8_t b = 0; b < NUM_KEYS; b++) { + // If button was just pressed, redraw inverted button + if (key[b].justPressed()) { + Serial.println("Button " + (String)b + " pressed"); + key[b].drawButton(true, "ML_DATUM + " + (String)(b * 10) + "px"); + } + + // If button was just released, redraw normal color button + if (key[b].justReleased()) { + Serial.println("Button " + (String)b + " released"); + key[b].drawButton(false, "ML_DATUM + " + (String)(b * 10) + "px"); + } + } + +} + +void drawButtons() +{ + // Generate buttons with different size X deltas + for (int i = 0; i < NUM_KEYS; i++) + { + key[i].initButton(&tft, + KEY_X + 0 * (KEY_W + KEY_SPACING_X), + KEY_Y + i * (KEY_H + KEY_SPACING_Y), // x, y, w, h, outline, fill, text + KEY_W, + KEY_H, + TFT_BLACK, // Outline + TFT_CYAN, // Fill + TFT_BLACK, // Text + "", // 10 Byte Label + KEY_TEXTSIZE); + + // Adjust button label X delta according to array position + // setLabelDatum(uint16_t x_delta, uint16_t y_delta, uint8_t datum) + key[i].setLabelDatum(i * 10, 0, ML_DATUM); + + // Draw button and specify label string + // Specifying label string here will allow more than the default 10 byte label + key[i].drawButton(false, "ML_DATUM + " + (String)(i * 10) + "px"); + } +} + +void touch_calibrate() +{ + uint16_t calData[5]; + uint8_t calDataOK = 0; + + // check file system exists + if (!SPIFFS.begin()) { + Serial.println("Formating file system"); + SPIFFS.format(); + SPIFFS.begin(); + } + + // check if calibration file exists and size is correct + if (SPIFFS.exists(CALIBRATION_FILE)) { + if (REPEAT_CAL) + { + // Delete if we want to re-calibrate + SPIFFS.remove(CALIBRATION_FILE); + } + else + { + File f = SPIFFS.open(CALIBRATION_FILE, "r"); + if (f) { + if (f.readBytes((char *)calData, 14) == 14) + calDataOK = 1; + f.close(); + } + } + } + + if (calDataOK && !REPEAT_CAL) { + // calibration data valid + tft.setTouch(calData); + } else { + // data not valid so recalibrate + tft.fillScreen(TFT_BLACK); + tft.setCursor(20, 0); + tft.setTextFont(2); + tft.setTextSize(1); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + + tft.println("Touch corners as indicated"); + + tft.setTextFont(1); + tft.println(); + + if (REPEAT_CAL) { + tft.setTextColor(TFT_RED, TFT_BLACK); + tft.println("Set REPEAT_CAL to false to stop this running again!"); + } + + tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15); + + tft.setTextColor(TFT_GREEN, TFT_BLACK); + tft.println("Calibration complete!"); + + // store data + File f = SPIFFS.open(CALIBRATION_FILE, "w"); + if (f) { + f.write((const unsigned char *)calData, 14); + f.close(); + } + } +}