#include "SPI.h"
#include "TFT_eSPI.h"
// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
#define BUTTON_W 150
#define BUTTON_H 30
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
TFT_eSPI tft = TFT_eSPI();
// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
struct BUTTON{
char* label;
int16_t x = (tft.width() - BUTTON_W) / 2;
int16_t y;
bool selected = false;
uint16_t w = BUTTON_W;
uint16_t h = BUTTON_H;
uint16_t fillcolor = ILI9341_RED;
uint16_t fillcolornormal = ILI9341_RED;
uint16_t fillcolorhovered = ILI9341_BLUE;
uint16_t textcolor = ILI9341_BLACK;
uint8_t textsize = 2;
};
// текст и данные для каждой кнопки
char* BUTTON_LABELS[] = {"Sound", "Sound level", "Magnetometer", "RadioData", "Infrared"};
BUTTON buttons[] = {{}, {}, {}, {}, {}};
BUTTON drawButton(BUTTON btn) {
// отрисовка кнопок
if(btn.selected) {
btn.fillcolor = btn.fillcolorhovered;
} else {
btn.fillcolor = btn.fillcolornormal;
}
uint16_t textLen = strlen(btn.label);
//Serial.println(textLen);
tft.fillRect(btn.x, btn.y, btn.w, btn.h, btn.fillcolor);
tft.setTextSize(btn.textsize);
tft.setTextColor(btn.textcolor);
/*Serial.print(btn.x);
Serial.print("+");
Serial.print((btn.x /2) - (textLen));
Serial.println("");*/
tft.setCursor(btn.x + 5, btn.y + (btn.h / 2) - btn.textsize*2);
tft.print(btn.label);
return btn;
}
BUTTON createButton(int16_t x, int16_t y, char* label, uint16_t w = -1, uint16_t h = -1, uint16_t fill = -1);
BUTTON createButton(int16_t x, int16_t y, char* label, uint16_t w, uint16_t h, uint16_t fill) {
struct BUTTON btn = {};
if(x>-1){
btn.x = x;
}
btn.y = y;
Serial.println(label);
btn.label = label;
if(w>-1){
btn.w = w;
}
if(h>-1){
btn.h = h;
}
if(fill>-1){
btn.fillcolor = fill;
}
return drawButton(btn);
}
bool isHovered(int index, int16_t x, int16_t y) {
int16_t buttonX = buttons[index].x;
int16_t buttonY = buttons[index].y;
buttons[index].selected = (x >= buttonX && x < buttonX + BUTTON_W && y >= buttonY && y < buttonY + BUTTON_H);
if(buttons[index].selected) {
Serial.println("isHovered: true");
} else {
Serial.println("isHovered: false");
}
return buttons[index].selected;
}
uint8_t buttonCount = 0;
void initButtons() {
//uint16_t x = (tft.width() - BUTTON_W) / 2;
uint16_t y = tft.height() / 2 - BUTTON_H - 10;
buttonCount = sizeof(BUTTON_LABELS)/sizeof(BUTTON_LABELS[0]);
for (int i = 0; i < buttonCount; i++) {
buttons[i] = createButton(-1, y, BUTTON_LABELS[i]);
y += buttons[i].textsize + BUTTON_H;
}
tft.fillRect(buttons[0].x, BUTTON_H+2, BUTTON_W, BUTTON_H, ILI9341_BLUE);
tft.fillRect(buttons[0].x, 2+BUTTON_H*2, BUTTON_W, BUTTON_H, ILI9341_YELLOW);
}
void selectMenu(uint16_t item) {
tft.fillScreen(ILI9341_BLACK);
char* backButton = "Main menu";
char* title = "Menu";
if(item > 0){
title = BUTTON_LABELS[item - 1];
}
uint16_t _y = tft.height() - BUTTON_H;
uint16_t _w = tft.width() / 2;
createButton(-1, 0, title);
switch (item) {
case 0:
initButtons();
break;
case 1:
//"Sound"
createButton(-1, tft.height() - BUTTON_H, backButton);
break;
case 2:
//"Sound level"
createButton(-1, tft.height() - BUTTON_H, backButton);
break;
case 3:
//"Magnetometer"
createButton(0, _y, "Calibrate", _w);
createButton(_w+1, _y, backButton);
break;
case 4:
//"RadioData"
createButton(-1, tft.height() - BUTTON_H, backButton);
break;
case 5:
//"Infrared"
createButton(-1, tft.height() - BUTTON_H, backButton);
break;
}
}
void setup() {
Serial.begin(9600);
Serial.println("ILI9341 Test!");
tft.begin();
// read diagnostics (optional but can help debug problems)
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDMADCTL);
Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDPIXFMT);
Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDIMGFMT);
Serial.print("Image Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDSELFDIAG);
Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
Serial.println(F("Benchmark Time (microseconds)"));
delay(10);
Serial.print(F("Rounded rects (filled) "));
//Serial.println(testFilledRoundRects());
delay(500);
Serial.println(F("Done!"));
//initButtons();
createButton(-1, 0, "Loading..");
}
void loop(void) {
for(uint8_t item=0; item<6; item++) {
selectMenu(item);
//testText();
delay(2000);
}
}
unsigned long testText() {
tft.fillScreen(ILI9341_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
}
unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(ILI9341_BLACK);
start = micros();
i=min(tft.width(), tft.height());
i2 = i / 2;
tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
//yield();
return micros() - start;
}