Adding a new folder for LVGL project

This commit is contained in:
Eric
2020-08-28 13:29:36 -07:00
parent bb1a36a18a
commit d1cf421190
12 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,370 @@
/*
Adapted from the Adafruit graphicstest sketch, see orignal header at end
of sketch.
This sketch uses the GLCD font (font 1) only.
Make sure all the display driver and pin comnenctions are correct by
editting the User_Setup.h file in the TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
#include "SPI.h"
#include "TFT_eSPI.h"
TFT_eSPI tft = TFT_eSPI();
unsigned long total = 0;
unsigned long tn = 0;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println(""); Serial.println("");
Serial.println("TFT_eSPI library test!");
tft.init();
tn = micros();
tft.fillScreen(TFT_BLACK);
yield(); Serial.println(F("Benchmark Time (microseconds)"));
yield(); Serial.print(F("Screen fill "));
yield(); Serial.println(testFillScreen());
//total+=testFillScreen();
//delay(500);
yield(); Serial.print(F("Text "));
yield(); Serial.println(testText());
//total+=testText();
//delay(3000);
yield(); Serial.print(F("Lines "));
yield(); Serial.println(testLines(TFT_CYAN));
//total+=testLines(TFT_CYAN);
//delay(500);
yield(); Serial.print(F("Horiz/Vert Lines "));
yield(); Serial.println(testFastLines(TFT_RED, TFT_BLUE));
//total+=testFastLines(TFT_RED, TFT_BLUE);
//delay(500);
yield(); Serial.print(F("Rectangles (outline) "));
yield(); Serial.println(testRects(TFT_GREEN));
//total+=testRects(TFT_GREEN);
//delay(500);
yield(); Serial.print(F("Rectangles (filled) "));
yield(); Serial.println(testFilledRects(TFT_YELLOW, TFT_MAGENTA));
//total+=testFilledRects(TFT_YELLOW, TFT_MAGENTA);
//delay(500);
yield(); Serial.print(F("Circles (filled) "));
yield(); Serial.println(testFilledCircles(10, TFT_MAGENTA));
//total+= testFilledCircles(10, TFT_MAGENTA);
yield(); Serial.print(F("Circles (outline) "));
yield(); Serial.println(testCircles(10, TFT_WHITE));
//total+=testCircles(10, TFT_WHITE);
//delay(500);
yield(); Serial.print(F("Triangles (outline) "));
yield(); Serial.println(testTriangles());
//total+=testTriangles();
//delay(500);
yield(); Serial.print(F("Triangles (filled) "));
yield(); Serial.println(testFilledTriangles());
//total += testFilledTriangles();
//delay(500);
yield(); Serial.print(F("Rounded rects (outline) "));
yield(); Serial.println(testRoundRects());
//total+=testRoundRects();
//delay(500);
yield(); Serial.print(F("Rounded rects (filled) "));
yield(); Serial.println(testFilledRoundRects());
//total+=testFilledRoundRects();
//delay(500);
yield(); Serial.println(F("Done!")); yield();
//Serial.print(F("Total = ")); Serial.println(total);
//yield();Serial.println(millis()-tn);
}
void loop(void) {
for (uint8_t rotation = 0; rotation < 4; rotation++) {
tft.setRotation(rotation);
testText();
delay(2000);
}
}
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(TFT_BLACK);
tft.fillScreen(TFT_RED);
tft.fillScreen(TFT_GREEN);
tft.fillScreen(TFT_BLUE);
tft.fillScreen(TFT_BLACK);
return micros() - start;
}
unsigned long testText() {
tft.fillScreen(TFT_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(TFT_WHITE); tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(TFT_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(TFT_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(TFT_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
//tft.setTextColor(TFT_GREEN,TFT_BLACK);
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 testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(TFT_BLACK);
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing
yield();
tft.fillScreen(TFT_BLACK);
x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
yield();
tft.fillScreen(TFT_BLACK);
x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
yield();
tft.fillScreen(TFT_BLACK);
x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
yield();
return micros() - start;
}
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height();
tft.fillScreen(TFT_BLACK);
start = micros();
for (y = 0; y < h; y += 5) tft.drawFastHLine(0, y, w, color1);
for (x = 0; x < w; x += 5) tft.drawFastVLine(x, 0, h, color2);
return micros() - start;
}
unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;
tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
start = micros();
for (i = 2; i < n; i += 6) {
i2 = i / 2;
tft.drawRect(cx - i2, cy - i2, i, i, color);
}
return micros() - start;
}
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
for (i = n - 1; i > 0; i -= 6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx - i2, cy - i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx - i2, cy - i2, i, i, color2);
}
return t;
}
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
tft.fillScreen(TFT_BLACK);
start = micros();
for (x = radius; x < w; x += r2) {
for (y = radius; y < h; y += r2) {
tft.fillCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, r2 = radius * 2,
w = tft.width() + radius,
h = tft.height() + radius;
// Screen is not cleared for this one -- this is
// intentional and does not affect the reported time.
start = micros();
for (x = 0; x < w; x += r2) {
for (y = 0; y < h; y += r2) {
tft.drawCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testTriangles() {
unsigned long start;
int n, i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
n = min(cx, cy);
start = micros();
for (i = 0; i < n; i += 5) {
tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(0, 0, i));
}
return micros() - start;
}
unsigned long testFilledTriangles() {
unsigned long start, t = 0;
int i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
start = micros();
for (i = min(cx, cy); i > 10; i -= 5) {
start = micros();
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i, i));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i, i, 0));
}
return t;
}
unsigned long testRoundRects() {
unsigned long start;
int w, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
w = min(tft.width(), tft.height());
start = micros();
for (i = 0; i < w; i += 6) {
i2 = i / 2;
tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(i, 0, 0));
}
return micros() - start;
}
unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
start = micros();
for (i = min(tft.width(), tft.height()); i > 20; i -= 6) {
i2 = i / 2;
tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
yield();
}
return micros() - start;
}
/***************************************************
Original Adafruit text:
This is an example sketch for the Adafruit 2.2" SPI display.
This library works with the Adafruit 2.2" TFT Breakout w/SD card
----> http://www.adafruit.com/products/1480
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate, 4 or 5 pins are required to
interface (RST is optional)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/

View File

@@ -0,0 +1,77 @@
#include "SPIFFS.h"
#include <SPI.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#define CALIBRATION_FILE "/calibrationData"
void setup(void) {
uint16_t calibrationData[5];
uint8_t calDataOK = 0;
Serial.begin(115200);
Serial.println("starting");
tft.init();
tft.setRotation(3);
tft.fillScreen((0xFFFF));
tft.setCursor(20, 0, 2);
tft.setTextColor(TFT_BLACK, TFT_WHITE); tft.setTextSize(1);
tft.println("calibration run");
// check file system
if (SPIFFS.begin(true)) { // always formatting
Serial.println("formating file system");
SPIFFS.format();
SPIFFS.begin();
}
// check if calibration file exists
if (SPIFFS.exists(CALIBRATION_FILE)) {
File f = SPIFFS.open(CALIBRATION_FILE, "r");
if (f) {
if (f.readBytes((char *)calibrationData, 14) == 14)
calDataOK = 1;
f.close();
}
}
if (calDataOK) {
// calibration data valid
tft.setTouch(calibrationData);
} else {
// data not valid. recalibrate
tft.calibrateTouch(calibrationData, TFT_WHITE, TFT_RED, 15);
// store data
File f = SPIFFS.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calibrationData, 14);
f.close();
}
for(int i=0; i<5; i++){
Serial.printf("%d,%d\n",i, calibrationData[i]);
}
}
tft.fillScreen((0xFFFF));
}
void loop() {
uint16_t x, y;
static uint16_t color;
if (tft.getTouch(&x, &y)) {
tft.setCursor(5, 5, 2);
tft.printf("x: %i ", x);
tft.setCursor(5, 20, 2);
tft.printf("y: %i ", y);
tft.drawPixel(x, y, color);
color += 155;
}
}

View File

@@ -0,0 +1,288 @@
/*
The TFT_eSPI library incorporates an Adafruit_GFX compatible
button handling class, this sketch is based on the Arduin-o-phone
example.
This example diplays a keypad where numbers can be entered and
send to the Serial Monitor window.
The sketch has been tested on the ESP8266 (which supports SPIFFS)
The minimum screen size is 320 x 240 as that is the keypad size.
TOUCH_CS and SPI_TOUCH_FREQUENCY must be defined in the User_Setup.h file
for the touch functions to do anything.
*/
// The SPIFFS (FLASH filing system) is used to hold touch screen
// calibration data
#include "FS.h"
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
// 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 "/TouchCalData2"
// 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 40 // Centre of key
#define KEY_Y 96
#define KEY_W 62 // Width and height
#define KEY_H 30
#define KEY_SPACING_X 18 // X and Y gap
#define KEY_SPACING_Y 20
#define KEY_TEXTSIZE 1 // Font size multiplier
// Using two fonts since numbers are nice when bold
#define LABEL1_FONT &FreeSansOblique12pt7b // Key label font 1
#define LABEL2_FONT &FreeSansBold12pt7b // Key label font 2
// Numeric display box size and location
#define DISP_X 1
#define DISP_Y 10
#define DISP_W 238
#define DISP_H 50
#define DISP_TSIZE 3
#define DISP_TCOLOR TFT_CYAN
// Number length, buffer for storing it and character index
#define NUM_LEN 12
char numberBuffer[NUM_LEN + 1] = "";
uint8_t numberIndex = 0;
// We have a status line for messages
#define STATUS_X 120 // Centred on this
#define STATUS_Y 65
// Create 15 keys for the keypad
char keyLabel[15][5] = {"New", "Del", "Send", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "0", "#" };
uint16_t keyColor[15] = {TFT_RED, TFT_DARKGREY, TFT_DARKGREEN,
TFT_BLUE, TFT_BLUE, TFT_BLUE,
TFT_BLUE, TFT_BLUE, TFT_BLUE,
TFT_BLUE, TFT_BLUE, TFT_BLUE,
TFT_BLUE, TFT_BLUE, TFT_BLUE
};
// Invoke the TFT_eSPI button class and create all the button objects
TFT_eSPI_Button key[15];
//------------------------------------------------------------------------------------------
void setup() {
// Use serial port
Serial.begin(115200);
// Initialise the TFT screen
tft.init();
// Set the rotation before we calibrate
tft.setRotation(3);
// Calibrate the touch screen and retrieve the scaling factors
//touch_calibrate();
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
// Clear the screen
tft.fillScreen(TFT_BLACK);
// Draw keypad background
tft.fillRect(0, 0, 240, 320, TFT_DARKGREY);
// Draw number display area and frame
tft.fillRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_BLACK);
tft.drawRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_WHITE);
// Draw keypad
drawKeypad();
}
//------------------------------------------------------------------------------------------
void loop(void) {
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
// Pressed will be set true is there is a valid touch on the screen
boolean pressed = tft.getTouch(&t_x, &t_y);
// / Check if any key coordinate boxes contain the touch coordinates
for (uint8_t b = 0; b < 15; 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 < 15; b++) {
if (b < 3) tft.setFreeFont(LABEL1_FONT);
else tft.setFreeFont(LABEL2_FONT);
if (key[b].justReleased()) key[b].drawButton(); // draw normal
if (key[b].justPressed()) {
key[b].drawButton(true); // draw invert
// if a numberpad button, append the relevant # to the numberBuffer
if (b >= 3) {
if (numberIndex < NUM_LEN) {
numberBuffer[numberIndex] = keyLabel[b][0];
numberIndex++;
numberBuffer[numberIndex] = 0; // zero terminate
}
status(""); // Clear the old status
}
// Del button, so delete last char
if (b == 1) {
numberBuffer[numberIndex] = 0;
if (numberIndex > 0) {
numberIndex--;
numberBuffer[numberIndex] = 0;//' ';
}
status(""); // Clear the old status
}
if (b == 2) {
status("Sent value to serial port");
Serial.println(numberBuffer);
}
// we dont really check that the text field makes sense
// just try to call
if (b == 0) {
status("Value cleared");
numberIndex = 0; // Reset index to 0
numberBuffer[numberIndex] = 0; // Place null in buffer
}
// Update the number display field
tft.setTextDatum(TL_DATUM); // Use top left corner as text coord datum
tft.setFreeFont(&FreeSans18pt7b); // Choose a nicefont that fits box
tft.setTextColor(DISP_TCOLOR); // Set the font colour
// Draw the string, the value returned is the width in pixels
int xwidth = tft.drawString(numberBuffer, DISP_X + 4, DISP_Y + 12);
// Now cover up the rest of the line up by drawing a black rectangle. No flicker this way
// but it will not work with italic or oblique fonts due to character overlap.
tft.fillRect(DISP_X + 4 + xwidth, DISP_Y + 1, DISP_W - xwidth - 5, DISP_H - 2, TFT_BLACK);
delay(10); // UI debouncing
}
}
}
//------------------------------------------------------------------------------------------
void drawKeypad()
{
// Draw the keys
for (uint8_t row = 0; row < 5; row++) {
for (uint8_t col = 0; col < 3; col++) {
uint8_t b = col + row * 3;
if (b < 3) tft.setFreeFont(LABEL1_FONT);
else tft.setFreeFont(LABEL2_FONT);
key[b].initButton(&tft, KEY_X + col * (KEY_W + KEY_SPACING_X),
KEY_Y + row * (KEY_H + KEY_SPACING_Y), // x, y, w, h, outline, fill, text
KEY_W, KEY_H, TFT_WHITE, keyColor[b], TFT_WHITE,
keyLabel[b], KEY_TEXTSIZE);
key[b].drawButton();
}
}
}
//------------------------------------------------------------------------------------------
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();
}
}
}
//------------------------------------------------------------------------------------------
// Print something in the mini status bar
void status(const char *msg) {
tft.setTextPadding(240);
//tft.setCursor(STATUS_X, STATUS_Y);
tft.setTextColor(TFT_WHITE, TFT_DARKGREY);
tft.setTextFont(0);
tft.setTextDatum(TC_DATUM);
tft.setTextSize(1);
tft.drawString(msg, STATUS_X, STATUS_Y);
}
//------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,108 @@
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 20
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
#if USE_LV_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{
Serial.printf("%s@%d->%s\r\n", file, line, dsc);
delay(100);
}
#endif
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
/* Reading input device (simulated encoder here) */
bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data)
{
static int32_t last_diff = 0;
int32_t diff = 0; /* Dummy - no movement */
int btn_state = LV_INDEV_STATE_REL; /* Dummy - no press */
data->enc_diff = diff - last_diff;;
data->state = btn_state;
last_diff = diff;
return false;
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
#if USE_LV_LOG != 0
lv_log_register_print(my_print); /* register print function for debugging */
#endif
tft.begin(); /* TFT init */
tft.setRotation(3); /* Landscape orientation */
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 480;
disp_drv.ver_res = 320;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
/*Initialize the touch pad*/
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = read_encoder;
lv_indev_drv_register(&indev_drv);
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
/* Create simple label */
lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Hello Arduino! (V6.1)");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}

View File

@@ -0,0 +1,200 @@
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void slider_event_cb(lv_obj_t * slider, lv_event_t event)
{
printEvent("Slider", event);
if(event == LV_EVENT_VALUE_CHANGED) {
static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */
snprintf(buf, 4, "%u", lv_slider_get_value(slider));
lv_label_set_text(slider_label, buf); /*Refresh the text*/
}
}
void printEvent(String Event, lv_event_t event)
{
Serial.print(Event);
printf(" ");
switch(event) {
case LV_EVENT_PRESSED:
printf("Pressed\n");
break;
case LV_EVENT_SHORT_CLICKED:
printf("Short clicked\n");
break;
case LV_EVENT_CLICKED:
printf("Clicked\n");
break;
case LV_EVENT_LONG_PRESSED:
printf("Long press\n");
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
printf("Long press repeat\n");
break;
case LV_EVENT_RELEASED:
printf("Released\n");
break;
}
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
//Set the theme..
lv_theme_t * th = lv_theme_night_init(210, NULL); //Set a HUE value and a Font for the Night Theme
lv_theme_set_current(th);
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
//lv_obj_t * tv = lv_tabview_create(scr, NULL);
//lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
/* Create simple label */
lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Hello Arduino! (V6.1)");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -50);
/* Create a slider in the center of the display */
lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
lv_obj_set_width(slider, screenWidth-50); /*Set the width*/
lv_obj_set_height(slider, 50);
lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)*/
lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function*/
/* Create a label below the slider */
slider_label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(slider_label, "0");
lv_obj_set_auto_realign(slider, true);
lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}

View File

@@ -0,0 +1,437 @@
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
//Set the theme..
lv_theme_t * th = lv_theme_night_init(210, NULL); //Set a HUE value and a Font for the Night Theme
lv_test_theme_1(th);
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
/**********************
* STATIC PROTOTYPES
**********************/
static void create_tab1(lv_obj_t * parent);
static void create_tab2(lv_obj_t * parent);
static void create_tab3(lv_obj_t * parent);
void lv_test_theme_1(lv_theme_t * th)
{
lv_theme_set_current(th);
th = lv_theme_get_current(); /*If `LV_THEME_LIVE_UPDATE 1` `th` is not used directly so get the real theme after set*/
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
lv_obj_t * tv = lv_tabview_create(scr, NULL);
lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_t * tab1 = lv_tabview_add_tab(tv, "Tab 1");
lv_obj_t * tab2 = lv_tabview_add_tab(tv, "Tab 2");
lv_obj_t * tab3 = lv_tabview_add_tab(tv, "Tab 3");
create_tab1(tab1);
create_tab2(tab2);
create_tab3(tab3);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void create_tab1(lv_obj_t * parent)
{
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
lv_theme_t * th = lv_theme_get_current();
static lv_style_t h_style;
lv_style_copy(&h_style, &lv_style_transp);
h_style.body.padding.inner = LV_DPI / 10;
h_style.body.padding.left = LV_DPI / 4;
h_style.body.padding.right = LV_DPI / 4;
h_style.body.padding.top = LV_DPI / 10;
h_style.body.padding.bottom = LV_DPI / 10;
lv_obj_t * h = lv_cont_create(parent, NULL);
lv_obj_set_style(h, &h_style);
lv_obj_set_click(h, false);
lv_cont_set_fit(h, LV_FIT_TIGHT);
lv_cont_set_layout(h, LV_LAYOUT_COL_M);
lv_obj_t * btn = lv_btn_create(h, NULL);
lv_btn_set_fit(btn, LV_FIT_TIGHT);
lv_btn_set_toggle(btn, true);
lv_obj_t * btn_label = lv_label_create(btn, NULL);
lv_label_set_text(btn_label, "Button");
btn = lv_btn_create(h, btn);
lv_btn_toggle(btn);
btn_label = lv_label_create(btn, NULL);
lv_label_set_text(btn_label, "Toggled");
btn = lv_btn_create(h, btn);
lv_btn_set_state(btn, LV_BTN_STATE_INA);
btn_label = lv_label_create(btn, NULL);
lv_label_set_text(btn_label, "Inactive");
lv_obj_t * label = lv_label_create(h, NULL);
lv_label_set_text(label, "Primary");
lv_obj_set_style(label, th->style.label.prim);
label = lv_label_create(h, NULL);
lv_label_set_text(label, "Secondary");
lv_obj_set_style(label, th->style.label.sec);
label = lv_label_create(h, NULL);
lv_label_set_text(label, "Hint");
lv_obj_set_style(label, th->style.label.hint);
static const char * btnm_str[] = {"1", "2", "3", LV_SYMBOL_OK, LV_SYMBOL_CLOSE, ""};
lv_obj_t * btnm = lv_btnm_create(h, NULL);
lv_obj_set_size(btnm, lv_disp_get_hor_res(NULL) / 4, 2 * LV_DPI / 3);
lv_btnm_set_map(btnm, btnm_str);
lv_btnm_set_btn_ctrl_all(btnm, LV_BTNM_CTRL_TGL_ENABLE);
lv_btnm_set_one_toggle(btnm, true);
lv_obj_t * table = lv_table_create(h, NULL);
lv_table_set_col_cnt(table, 3);
lv_table_set_row_cnt(table, 4);
lv_table_set_col_width(table, 0, LV_DPI / 3);
lv_table_set_col_width(table, 1, LV_DPI / 2);
lv_table_set_col_width(table, 2, LV_DPI / 2);
lv_table_set_cell_merge_right(table, 0, 0, true);
lv_table_set_cell_merge_right(table, 0, 1, true);
lv_table_set_cell_value(table, 0, 0, "Table");
lv_table_set_cell_align(table, 0, 0, LV_LABEL_ALIGN_CENTER);
lv_table_set_cell_value(table, 1, 0, "1");
lv_table_set_cell_value(table, 1, 1, "13");
lv_table_set_cell_align(table, 1, 1, LV_LABEL_ALIGN_RIGHT);
lv_table_set_cell_value(table, 1, 2, "ms");
lv_table_set_cell_value(table, 2, 0, "2");
lv_table_set_cell_value(table, 2, 1, "46");
lv_table_set_cell_align(table, 2, 1, LV_LABEL_ALIGN_RIGHT);
lv_table_set_cell_value(table, 2, 2, "ms");
lv_table_set_cell_value(table, 3, 0, "3");
lv_table_set_cell_value(table, 3, 1, "61");
lv_table_set_cell_align(table, 3, 1, LV_LABEL_ALIGN_RIGHT);
lv_table_set_cell_value(table, 3, 2, "ms");
h = lv_cont_create(parent, h);
lv_obj_t * sw_h = lv_cont_create(h, NULL);
lv_cont_set_style(sw_h, LV_CONT_STYLE_MAIN, &lv_style_transp);
lv_cont_set_fit2(sw_h, LV_FIT_NONE, LV_FIT_TIGHT);
lv_obj_set_width(sw_h, LV_HOR_RES / 4);
lv_cont_set_layout(sw_h, LV_LAYOUT_PRETTY);
lv_obj_t * sw = lv_sw_create(sw_h, NULL);
lv_sw_set_anim_time(sw, 250);
sw = lv_sw_create(sw_h, sw);
lv_sw_on(sw, LV_ANIM_OFF);
lv_obj_t * bar = lv_bar_create(h, NULL);
lv_bar_set_value(bar, 70, false);
lv_obj_t * slider = lv_slider_create(h, NULL);
lv_bar_set_value(slider, 70, false);
lv_obj_t * line = lv_line_create(h, NULL);
static lv_point_t line_p[2];
line_p[0].x = 0;
line_p[0].y = 0;
line_p[1].x = lv_disp_get_hor_res(NULL) / 5;
line_p[1].y = 0;
lv_line_set_points(line, line_p, 2);
lv_line_set_style(line, LV_LINE_STYLE_MAIN, th->style.line.decor);
lv_obj_t * cb = lv_cb_create(h, NULL);
cb = lv_cb_create(h, cb);
lv_btn_set_state(cb, LV_BTN_STATE_TGL_REL);
lv_obj_t * ddlist = lv_ddlist_create(h, NULL);
lv_ddlist_set_fix_width(ddlist, lv_obj_get_width(ddlist) + LV_DPI / 2); /*Make space for the arrow*/
lv_ddlist_set_draw_arrow(ddlist, true);
h = lv_cont_create(parent, h);
lv_obj_t * list = lv_list_create(h, NULL);
lv_obj_set_size(list, lv_disp_get_hor_res(NULL) / 4, lv_disp_get_ver_res(NULL) / 2);
lv_obj_t * list_btn;
list_btn = lv_list_add_btn(list, LV_SYMBOL_GPS, "GPS");
lv_btn_set_toggle(list_btn, true);
lv_list_add_btn(list, LV_SYMBOL_WIFI, "WiFi");
lv_list_add_btn(list, LV_SYMBOL_GPS, "GPS");
lv_list_add_btn(list, LV_SYMBOL_AUDIO, "Audio");
lv_list_add_btn(list, LV_SYMBOL_VIDEO, "Video");
lv_list_add_btn(list, LV_SYMBOL_CALL, "Call");
lv_list_add_btn(list, LV_SYMBOL_BELL, "Bell");
lv_list_add_btn(list, LV_SYMBOL_FILE, "File");
lv_list_add_btn(list, LV_SYMBOL_EDIT, "Edit");
lv_list_add_btn(list, LV_SYMBOL_CUT, "Cut");
lv_list_add_btn(list, LV_SYMBOL_COPY, "Copy");
lv_obj_t * roller = lv_roller_create(h, NULL);
lv_roller_set_options(roller, "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday", true);
lv_roller_set_selected(roller, 1, false);
lv_roller_set_visible_row_count(roller, 3);
}
static void create_tab2(lv_obj_t * parent)
{
lv_coord_t w = lv_page_get_scrl_width(parent);
lv_obj_t * chart = lv_chart_create(parent, NULL);
lv_chart_set_type(chart, LV_CHART_TYPE_AREA);
lv_obj_set_size(chart, w / 3, lv_disp_get_ver_res(NULL) / 3);
lv_obj_set_pos(chart, LV_DPI / 10, LV_DPI / 10);
lv_chart_series_t * s1 = lv_chart_add_series(chart, LV_COLOR_RED);
lv_chart_set_next(chart, s1, 30);
lv_chart_set_next(chart, s1, 20);
lv_chart_set_next(chart, s1, 10);
lv_chart_set_next(chart, s1, 12);
lv_chart_set_next(chart, s1, 20);
lv_chart_set_next(chart, s1, 27);
lv_chart_set_next(chart, s1, 35);
lv_chart_set_next(chart, s1, 55);
lv_chart_set_next(chart, s1, 70);
lv_chart_set_next(chart, s1, 75);
lv_obj_t * gauge = lv_gauge_create(parent, NULL);
lv_gauge_set_value(gauge, 0, 40);
lv_obj_set_size(gauge, w / 4, w / 4);
lv_obj_align(gauge, chart, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
lv_obj_t * arc = lv_arc_create(parent, NULL);
lv_obj_align(arc, gauge, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_DPI / 8);
lv_obj_t * ta = lv_ta_create(parent, NULL);
lv_obj_set_size(ta, w / 3, lv_disp_get_ver_res(NULL) / 4);
lv_obj_align(ta, NULL, LV_ALIGN_IN_TOP_RIGHT, -LV_DPI / 10, LV_DPI / 10);
lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK);
lv_obj_t * kb = lv_kb_create(parent, NULL);
lv_obj_set_size(kb, 2 * w / 3, lv_disp_get_ver_res(NULL) / 3);
lv_obj_align(kb, ta, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI);
lv_kb_set_ta(kb, ta);
#if LV_USE_ANIMATION
lv_obj_t * loader = lv_preload_create(parent, NULL);
lv_obj_align(loader, NULL, LV_ALIGN_CENTER, 0, - LV_DPI);
#endif
}
static void create_tab3(lv_obj_t * parent)
{
/*Create a Window*/
lv_obj_t * win = lv_win_create(parent, NULL);
lv_obj_t * win_btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE);
lv_obj_set_event_cb(win_btn, lv_win_close_event_cb);
lv_win_add_btn(win, LV_SYMBOL_DOWN);
lv_obj_set_size(win, lv_disp_get_hor_res(NULL) / 2, lv_disp_get_ver_res(NULL) / 2);
lv_obj_set_pos(win, LV_DPI / 20, LV_DPI / 20);
lv_obj_set_top(win, true);
/*Create a Label in the Window*/
lv_obj_t * label = lv_label_create(win, NULL);
lv_label_set_text(label, "Label in the window");
/*Create a Line meter in the Window*/
lv_obj_t * lmeter = lv_lmeter_create(win, NULL);
lv_obj_align(lmeter, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
lv_lmeter_set_value(lmeter, 70);
/*Create a 2 LEDs in the Window*/
lv_obj_t * led1 = lv_led_create(win, NULL);
lv_obj_align(led1, lmeter, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
lv_led_on(led1);
lv_obj_t * led2 = lv_led_create(win, NULL);
lv_obj_align(led2, led1, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
lv_led_off(led2);
/*Create a Page*/
lv_obj_t * page = lv_page_create(parent, NULL);
lv_obj_set_size(page, lv_disp_get_hor_res(NULL) / 3, lv_disp_get_ver_res(NULL) / 2);
lv_obj_set_top(page, true);
lv_obj_align(page, win, LV_ALIGN_IN_TOP_RIGHT, LV_DPI, LV_DPI);
label = lv_label_create(page, NULL);
lv_label_set_text(label, "Lorem ipsum dolor sit amet, repudiare voluptatibus pri cu.\n"
"Ei mundi pertinax posidonium eum, cum tempor maiorum at,\n"
"mea fuisset assentior ad. Usu cu suas civibus iudicabit.\n"
"Eum eu congue tempor facilisi. Tale hinc unum te vim.\n"
"Te cum populo animal eruditi, labitur inciderint at nec.\n\n"
"Eius corpora et quo. Everti voluptaria instructior est id,\n"
"vel in falli primis. Mea ei porro essent admodum,\n"
"his ei malis quodsi, te quis aeterno his.\n"
"Qui tritani recusabo reprehendunt ne,\n"
"per duis explicari at. Simul mediocritatem mei et.");
/*Create a Calendar*/
lv_obj_t * cal = lv_calendar_create(parent, NULL);
lv_obj_set_size(cal, 5 * LV_DPI / 2, 5 * LV_DPI / 2);
lv_obj_align(cal, page, LV_ALIGN_OUT_RIGHT_TOP, -LV_DPI / 2, LV_DPI / 3);
lv_obj_set_top(cal, true);
static lv_calendar_date_t highlighted_days[2];
highlighted_days[0].day = 5;
highlighted_days[0].month = 5;
highlighted_days[0].year = 2018;
highlighted_days[1].day = 8;
highlighted_days[1].month = 5;
highlighted_days[1].year = 2018;
lv_calendar_set_highlighted_dates(cal, highlighted_days, 2);
lv_calendar_set_today_date(cal, &highlighted_days[0]);
lv_calendar_set_showed_date(cal, &highlighted_days[0]);
/*Create a Message box*/
static const char * mbox_btn_map[] = {" ", "Got it!", " ", ""};
lv_obj_t * mbox = lv_mbox_create(parent, NULL);
lv_mbox_set_text(mbox, "Click on the window or the page to bring it to the foreground");
lv_mbox_add_btns(mbox, mbox_btn_map);
lv_btnm_set_btn_ctrl(lv_mbox_get_btnm(mbox), 0, LV_BTNM_CTRL_HIDDEN);
lv_btnm_set_btn_width(lv_mbox_get_btnm(mbox), 1, 7);
lv_btnm_set_btn_ctrl(lv_mbox_get_btnm(mbox), 2, LV_BTNM_CTRL_HIDDEN);
lv_obj_set_top(mbox, true);
}

View File

@@ -0,0 +1,159 @@
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
lv_ex_btn_1();
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
static void event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_CLICKED) {
printf("Clicked\n");
}
else if(event == LV_EVENT_VALUE_CHANGED) {
printf("Toggled\n");
}
}
void lv_ex_btn_1(void)
{
lv_obj_t * label;
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_event_cb(btn1, event_handler);
lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40);
label = lv_label_create(btn1, NULL);
lv_label_set_text(label, "Button");
lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_event_cb(btn2, event_handler);
lv_obj_align(btn2, NULL, LV_ALIGN_CENTER, 0, 40);
lv_btn_set_toggle(btn2, true);
lv_btn_toggle(btn2);
lv_btn_set_fit2(btn2, LV_FIT_NONE, LV_FIT_TIGHT);
label = lv_label_create(btn2, NULL);
lv_label_set_text(label, "Toggled");
}

View File

@@ -0,0 +1,170 @@
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
lv_main();
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
static lv_obj_t *kb;
static void lv_main(){
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
lv_obj_t * tv = lv_tabview_create(scr, NULL);
lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_t * tab1 = lv_tabview_add_tab(tv, "LIST TAB");
lv_obj_t * tab2 = lv_tabview_add_tab(tv, "WRITE TAB");
create_tab1(tab1);
create_tab2(tab2);
}
static void create_tab1(lv_obj_t * parent){
//List Tab
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
}
static void create_tab2(lv_obj_t * parent){
//Write Tab
lv_obj_t * ta = lv_ta_create(parent, NULL);
lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) / 2);
lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK);
lv_ta_set_text(ta, "hello!");
/*Create a keyboard and apply the styles*/
kb = lv_kb_create(parent, NULL);
lv_obj_set_size(kb, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) / 2 - 20);
lv_obj_set_event_cb(kb, keyboard_event_cb);
/*Assign the text area to the keyboard*/
lv_kb_set_ta(kb, ta);
}
static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event){
lv_kb_def_event_cb(kb, event);
if(event == LV_EVENT_APPLY){
printf("LV_EVENT_APPLY\n");
}else if(event == LV_EVENT_CANCEL){
printf("LV_EVENT_CANCEL\n");
}
}

View File

@@ -0,0 +1,211 @@
#include "SPIFFS.h"
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
String currentFileName;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
if(initSPIFFS()){
lv_main();
} else {
lv_error_page();
}
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
bool initSPIFFS(){
if(!SPIFFS.begin(true)){
return false;
}
return true;
}
static lv_obj_t *kb;
static void lv_main(){
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
lv_obj_t * tv = lv_tabview_create(scr, NULL);
lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_t * tab1 = lv_tabview_add_tab(tv, "LIST TAB");
lv_obj_t * tab2 = lv_tabview_add_tab(tv, "WRITE TAB");
create_tab1(tab1);
create_tab2(tab2);
}
static void lv_error_page(){
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Please check your SPIFFS");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0,0);
}
static void create_tab1(lv_obj_t * parent){
//List Tab
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
lv_obj_t * list = lv_list_create(parent, NULL);
lv_obj_set_size(list, lv_obj_get_width(parent)-20, lv_obj_get_height(parent)-20);
lv_obj_align(list, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10);
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_EDIT, "New");
lv_obj_set_event_cb(btn, file_list_event);
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file){
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, file.name());
lv_obj_set_event_cb(btn, file_list_event);
file = root.openNextFile();
}
}
static void create_tab2(lv_obj_t * parent){
//Write Tab
lv_obj_t * ta = lv_ta_create(parent, NULL);
lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) / 2);
lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK);
lv_ta_set_text(ta, "hello!");
/*Create a keyboard and apply the styles*/
kb = lv_kb_create(parent, NULL);
lv_obj_set_size(kb, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) / 2 - 20);
lv_obj_set_event_cb(kb, keyboard_event_cb);
/*Assign the text area to the keyboard*/
lv_kb_set_ta(kb, ta);
}
static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event){
lv_kb_def_event_cb(kb, event);
if(event == LV_EVENT_APPLY){
printf("LV_EVENT_APPLY\n");
}else if(event == LV_EVENT_CANCEL){
printf("LV_EVENT_CANCEL\n");
}
}
static void file_list_event(lv_obj_t * btn, lv_event_t e){
if(e == LV_EVENT_CLICKED){
currentFileName = lv_list_get_btn_text(btn);
Serial.println(currentFileName);
}
}

View File

@@ -0,0 +1,248 @@
#include "SPIFFS.h"
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
int screenWidth = 480;
int screenHeight = 320;
String currentFileName;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
if(initSPIFFS()){
lv_main();
} else {
lv_error_page();
}
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
bool initSPIFFS(){
if(!SPIFFS.begin(true)){
return false;
}
return true;
}
String openFile(String filename){
File file = SPIFFS.open(filename);
if(!file){
file.close();
return "";
}
String textData;
while(file.available()){
textData += char(file.read());
}
Serial.println(textData);
file.close();
return textData;
}
bool writeFile(String filename, String contents){
File file = SPIFFS.open(filename, FILE_WRITE);
if(!file){
file.close();
return false;
}
if(file.print(contents)){
file.close();
return true;
}
file.close();
return false;
}
static lv_obj_t *kb, *ta;
static void lv_main(){
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
lv_obj_t * tv = lv_tabview_create(scr, NULL);
lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_t * tab1 = lv_tabview_add_tab(tv, "LIST TAB");
lv_obj_t * tab2 = lv_tabview_add_tab(tv, "WRITE TAB");
create_tab1(tab1);
create_tab2(tab2);
}
static void lv_error_page(){
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Please check your SPIFFS");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0,0);
}
static void create_tab1(lv_obj_t * parent){
//List Tab
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
lv_obj_t * list = lv_list_create(parent, NULL);
lv_obj_set_size(list, lv_obj_get_width(parent)-20, lv_obj_get_height(parent)-20);
lv_obj_align(list, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10);
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_EDIT, "New");
lv_obj_set_event_cb(btn, file_list_event);
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file){
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, file.name());
lv_obj_set_event_cb(btn, file_list_event);
file = root.openNextFile();
}
}
static void create_tab2(lv_obj_t * parent){
//Write Tab
ta = lv_ta_create(parent, NULL);
lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) / 2);
lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK);
lv_ta_set_text(ta, "");
/*Create a keyboard and apply the styles*/
kb = lv_kb_create(parent, NULL);
lv_obj_set_size(kb, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) / 2 - 20);
lv_obj_set_event_cb(kb, keyboard_event_cb);
/*Assign the text area to the keyboard*/
lv_kb_set_ta(kb, ta);
}
static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event){
lv_kb_def_event_cb(kb, event);
if(event == LV_EVENT_APPLY){
printf("LV_EVENT_APPLY\n");
}else if(event == LV_EVENT_CANCEL){
printf("LV_EVENT_CANCEL\n");
}
}
static void file_list_event(lv_obj_t * btn, lv_event_t e){
if(e == LV_EVENT_CLICKED){
currentFileName = lv_list_get_btn_text(btn);
Serial.println(currentFileName);
if(strcmp(currentFileName.c_str(),"New") == 0){
lv_ta_set_text(ta, "");
}else{
lv_ta_set_text(ta, openFile(currentFileName).c_str());
}
}
}

View File

@@ -0,0 +1,373 @@
#include "SPIFFS.h"
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
int screenWidth = 480;
int screenHeight = 320;
String currentFileName;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
if(initSPIFFS()){
lv_main();
} else {
lv_error_page();
}
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
bool initSPIFFS(){
if(!SPIFFS.begin(true)){
return false;
}
return true;
}
String openFile(String filename){
File file = SPIFFS.open(filename) ;
if(!file){
file.close();
return "";
}
String textData;
while(file.available()){
textData += char(file.read());
}
Serial.println(textData);
file.close();
return textData;
}
bool writeFile(String filename, String contents){
File file = SPIFFS.open(filename, FILE_WRITE);
if(!file){
file.close();
return false;
}
if(file.print(contents)){
file.close();
return true;
}
file.close();
return false;
}
void deleteFile(String filename){
SPIFFS.remove(filename);
}
static lv_obj_t *kb, *ta, *mbox, *mbox_filename, *ta_filename;
static const char * modal_popup_btns[] = {"Save", "Save as", "Delete", "Cancel", ""};
static const char * filename_popup_btns[] ={"Apply", "Close", ""};
static void lv_main(){
lv_theme_t * th = lv_theme_night_init(210, NULL);
lv_theme_set_current(th);
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
lv_obj_t * tv = lv_tabview_create(scr, NULL);
lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_t * tab1 = lv_tabview_add_tab(tv, "LIST TAB");
lv_obj_t * tab2 = lv_tabview_add_tab(tv, "WRITE TAB");
create_tab1(tab1);
create_tab2(tab2);
}
static void lv_error_page(){
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Please check your SPIFFS");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0,0);
}
static void create_tab1(lv_obj_t * parent){
//List Tab
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
lv_obj_t * list = lv_list_create(parent, NULL);
lv_obj_set_size(list, lv_obj_get_width(parent)-20, lv_obj_get_height(parent)-20);
lv_obj_align(list, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10);
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_EDIT, "New");
lv_obj_set_event_cb(btn, file_list_event);
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file){
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, file.name());
lv_obj_set_event_cb(btn, file_list_event);
file = root.openNextFile();
}
}
static void create_tab2(lv_obj_t * parent){
//Write Tab
ta = lv_ta_create(parent, NULL);
lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) / 2);
lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK);
lv_ta_set_text(ta, "");
/*Create a keyboard and apply the styles*/
kb = lv_kb_create(parent, NULL);
lv_obj_set_size(kb, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) / 2 - 20);
lv_obj_set_event_cb(kb, keyboard_event_cb);
/*Assign the text area to the keyboard*/
lv_kb_set_ta(kb, ta);
}
static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event){
lv_kb_def_event_cb(kb, event);
if(event == LV_EVENT_APPLY){
printf("LV_EVENT_APPLY\n");
mbox_menu_modal();
}else if(event == LV_EVENT_CANCEL){
printf("LV_EVENT_CANCEL\n");
}
}
static void mbox_menu_modal(){
static lv_style_t modal_style;
/* Create a full-screen background */
lv_style_copy(&modal_style, &lv_style_plain_color);
/* Set the background's style */
modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK;
modal_style.body.opa = LV_OPA_50;
/* Create a base object for the modal background */
lv_obj_t *obj = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(obj, &modal_style);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);
lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */
/* Create the message box as a child of the modal background */
mbox = lv_mbox_create(obj, NULL);
lv_mbox_add_btns(mbox, modal_popup_btns);
lv_mbox_set_text(mbox, "Menu options!");
lv_obj_set_size(mbox, LV_HOR_RES - 100, LV_VER_RES - 50);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_event_cb(mbox, mbox_event_cb);
/* Fade the message box in with an animation */
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_time(&a, 500, 0);
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale);
lv_anim_create(&a);
}
static void mbox_event_cb(lv_obj_t *obj, lv_event_t evt)
{
if(evt == LV_EVENT_DELETE && obj == mbox) {
/* Delete the parent modal background */
lv_obj_del_async(lv_obj_get_parent(mbox));
mbox = NULL; /* happens before object is actually deleted! */
} else if(evt == LV_EVENT_VALUE_CHANGED) {
/* A button was clicked */
lv_mbox_start_auto_close(mbox, 0);
String contents = lv_ta_get_text(ta);
if(strcmp(lv_mbox_get_active_btn_text(obj), "Save")==0){
if(contents.length() > 0){
if(strcmp(currentFileName.c_str(),"New") == 0){
Serial.println("New Save");
open_mbox_filename();
}else{
if(writeFile(currentFileName, contents)){
Serial.println("Write Success");
}else{
//Error
}
}
}else{
//Nothing to write
}
}else if(strcmp(lv_mbox_get_active_btn_text(obj), "Save As")==0){
if(contents.length() > 0){
open_mbox_filename();
}
}else if(strcmp(lv_mbox_get_active_btn_text(obj), "Delete")==0){
if(strcmp(currentFileName.c_str(), "New")==0){
//Just go back to home screen
}else{
deleteFile(currentFileName);
}
}
}
}
static void open_mbox_filename(){
mbox_filename = lv_mbox_create(lv_scr_act(), NULL);
lv_mbox_set_text(mbox_filename, "File Name");
ta_filename = lv_ta_create(mbox_filename, NULL);
lv_obj_set_size(ta_filename, 200, 40);
lv_ta_set_cursor_type(ta_filename, LV_CURSOR_LINE);
lv_ta_set_text(ta_filename, "");
lv_mbox_add_btns(mbox_filename, filename_popup_btns);
lv_obj_set_width(mbox_filename, 200);
lv_obj_set_event_cb(mbox_filename, filename_event_handler);
lv_obj_align(mbox_filename, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the corner*/
lv_kb_set_ta(kb, ta_filename);
}
static void filename_event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
lv_mbox_start_auto_close(mbox_filename, 0);
printf("Button: %s\n", lv_mbox_get_active_btn_text(obj));
if(strcmp(lv_mbox_get_active_btn_text(obj), "Apply")==0){
String contents = lv_ta_get_text(ta);
String fileName = lv_ta_get_text(ta_filename);
if(fileName.length() > 0){
if(writeFile("/"+fileName, contents)){
//Write Success
}else{
//Cannot write to file
}
}else{
//Check the file name
}
}
}
}
static void file_list_event(lv_obj_t * btn, lv_event_t e){
if(e == LV_EVENT_CLICKED){
currentFileName = lv_list_get_btn_text(btn);
Serial.println(currentFileName);
if(strcmp(currentFileName.c_str(),"New") == 0){
lv_ta_set_text(ta, "");
}else{
lv_ta_set_text(ta, openFile(currentFileName).c_str());
}
}
}

View File

@@ -0,0 +1,432 @@
#include "SPIFFS.h"
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#define LVGL_TICK_PERIOD 60
Ticker tick; /* timer for interrupt handler */
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
int screenWidth = 480;
int screenHeight = 320;
String currentFileName;
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX <= screenWidth && touchY <=screenHeight)
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
data->point.x = touchX;
data->point.y = touchY;
}
return false; /*Return `false` because we are not buffering and no more data to read*/
}
/* Interrupt driven periodic handler */
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
lv_init();
tft.begin(); /* TFT init */
tft.setRotation(3);
//uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
uint16_t calData[5] = {299, 3588, 348, 3474, 1};
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
/*Initialize the graphics library's tick*/
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
if(initSPIFFS()){
lv_main();
} else {
lv_error_page();
}
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
delay(5);
}
bool initSPIFFS(){
if(!SPIFFS.begin(true)){
return false;
}
return true;
}
String openFile(String filename){
File file = SPIFFS.open(filename) ;
if(!file){
file.close();
return "";
}
String textData;
while(file.available()){
textData += char(file.read());
}
Serial.println(textData);
file.close();
return textData;
}
bool writeFile(String filename, String contents){
File file = SPIFFS.open(filename, FILE_WRITE);
if(!file){
file.close();
return false;
}
if(file.print(contents)){
file.close();
return true;
}
file.close();
return false;
}
void deleteFile(String filename){
SPIFFS.remove(filename);
}
static lv_obj_t *kb, *ta, *mbox, *mbox_filename, *ta_filename, *list, *header_label, *tv;
static const char * modal_popup_btns[] = {"Save", "Save As", "Delete", "Cancel", ""};
static const char * filename_popup_btns[] ={"Apply", "Close", ""};
static void lv_main(){
lv_theme_t * th = lv_theme_night_init(210, NULL);
lv_theme_set_current(th);
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
header_create();
tv = lv_tabview_create(scr, NULL);
lv_obj_set_pos(tv, 0, 40);
lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL) - 40);
lv_tabview_set_anim_time(tv, 50);
lv_obj_t * tab1 = lv_tabview_add_tab(tv, "LIST TAB");
lv_obj_t * tab2 = lv_tabview_add_tab(tv, "WRITE TAB");
lv_tabview_set_btns_hidden(tv, true);
lv_tabview_set_sliding(tv, false);
create_tab1(tab1);
create_tab2(tab2);
}
static void lv_error_page(){
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Please check your SPIFFS");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0,0);
}
static void header_create(){
lv_obj_t * header = lv_cont_create(lv_disp_get_scr_act(NULL), NULL);
lv_obj_set_width(header, lv_disp_get_hor_res(NULL));
lv_obj_set_event_cb(header, header_event);
lv_obj_t * sym = lv_label_create(header, NULL);
lv_label_set_text(sym, LV_SYMBOL_DIRECTORY);
lv_obj_align(sym, NULL, LV_ALIGN_IN_RIGHT_MID, -10, 0);
header_label = lv_label_create(header, NULL);
header_set_text("Simple Note");
lv_obj_align(header_label, NULL, LV_ALIGN_IN_LEFT_MID, 10, 0);
lv_cont_set_fit2(header, LV_FIT_NONE, LV_FIT_TIGHT);
lv_obj_set_pos(header, 0, 0);
}
static void header_set_text(String _name){
lv_label_set_text(header_label, _name.c_str());
}
static void header_event(lv_obj_t * btn, lv_event_t e){
if(e == LV_EVENT_CLICKED){
if(lv_tabview_get_tab_act(tv) != 0){
Serial.println("GO BACK TO HOME");
home_menu();
}
}
}
static void home_menu(){
header_set_text("Simple Note");
lv_tabview_set_tab_act(tv, 0, LV_ANIM_ON);
lv_ta_set_cursor_type(ta, LV_CURSOR_NONE);
}
static void refresh_list(){
if(list != NULL){
lv_list_clean(list);
}
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_EDIT, "New");
lv_obj_set_event_cb(btn, file_list_event);
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file){
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, file.name());
lv_obj_set_event_cb(btn, file_list_event);
file = root.openNextFile();
}
}
static void create_tab1(lv_obj_t * parent){
//List Tab
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
list = lv_list_create(parent, NULL);
lv_obj_set_size(list, lv_obj_get_width(parent)-20, lv_obj_get_height(parent)-20);
lv_obj_align(list, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10);
refresh_list();
}
static void create_tab2(lv_obj_t * parent){
//Write Tab
ta = lv_ta_create(parent, NULL);
lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) - 10);
lv_obj_set_event_cb(ta, text_area_event_handler);
lv_ta_set_cursor_type(ta, LV_CURSOR_NONE);
lv_ta_set_text(ta, "");
/*Create a keyboard and apply the styles*/
kb = lv_kb_create(parent, NULL);
lv_obj_set_size(kb, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) / 2 - 20);
lv_obj_set_event_cb(kb, keyboard_event_cb);
/*Assign the text area to the keyboard*/
lv_kb_set_ta(kb, ta);
}
static void text_area_event_handler(lv_obj_t * text_area, lv_event_t event){
lv_obj_t * parent = lv_obj_get_parent(lv_obj_get_parent(ta));
if(event == LV_EVENT_LONG_PRESSED){
lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) / 2);
lv_obj_move_foreground(kb);
lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK);
}
}
static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event){
lv_kb_def_event_cb(kb, event);
if(event == LV_EVENT_APPLY){
printf("LV_EVENT_APPLY\n");
mbox_menu_modal();
lv_ta_set_cursor_type(ta, LV_CURSOR_NONE);
}else if(event == LV_EVENT_CANCEL){
printf("LV_EVENT_CANCEL\n");
home_menu();
}
}
static void mbox_menu_modal(){
static lv_style_t modal_style;
/* Create a full-screen background */
lv_style_copy(&modal_style, &lv_style_plain_color);
/* Set the background's style */
modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK;
modal_style.body.opa = LV_OPA_50;
/* Create a base object for the modal background */
lv_obj_t *obj = lv_obj_create(lv_scr_act(), NULL);
lv_obj_set_style(obj, &modal_style);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);
lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */
/* Create the message box as a child of the modal background */
mbox = lv_mbox_create(obj, NULL);
lv_mbox_add_btns(mbox, modal_popup_btns);
lv_mbox_set_text(mbox, "Menu options!");
lv_obj_set_size(mbox, LV_HOR_RES - 100, LV_VER_RES - 50);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_event_cb(mbox, mbox_event_cb);
/* Fade the message box in with an animation */
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_time(&a, 500, 0);
lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER);
lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale);
lv_anim_create(&a);
}
static void mbox_event_cb(lv_obj_t *obj, lv_event_t evt)
{
if(evt == LV_EVENT_DELETE && obj == mbox) {
/* Delete the parent modal background */
lv_obj_del_async(lv_obj_get_parent(mbox));
mbox = NULL; /* happens before object is actually deleted! */
} else if(evt == LV_EVENT_VALUE_CHANGED) {
/* A button was clicked */
lv_mbox_start_auto_close(mbox, 0);
String contents = lv_ta_get_text(ta);
if(strcmp(lv_mbox_get_active_btn_text(obj), "Save")==0){
if(contents.length() > 0){
if(strcmp(currentFileName.c_str(),"New") == 0){
Serial.println("New Save");
open_mbox_filename();
}else{
if(writeFile(currentFileName, contents)){
Serial.println("Write Success");
refresh_list();
home_menu();
}else{
//Error
header_set_text("Cannot write to file");
}
}
}else{
//Nothing to write
header_set_text("Nothing to write");
}
}else if(strcmp(lv_mbox_get_active_btn_text(obj), "Save As")==0){
if(contents.length() > 0){
open_mbox_filename();
}
}else if(strcmp(lv_mbox_get_active_btn_text(obj), "Delete")==0){
if(strcmp(currentFileName.c_str(), "New")==0){
//Just go back to home screen
home_menu();
}else{
deleteFile(currentFileName);
refresh_list();
home_menu();
}
}
}
}
static void open_mbox_filename(){
mbox_filename = lv_mbox_create(lv_scr_act(), NULL);
lv_mbox_set_text(mbox_filename, "File Name");
ta_filename = lv_ta_create(mbox_filename, NULL);
lv_obj_set_size(ta_filename, 200, 40);
lv_ta_set_cursor_type(ta_filename, LV_CURSOR_LINE);
lv_ta_set_text(ta_filename, "");
lv_mbox_add_btns(mbox_filename, filename_popup_btns);
lv_obj_set_width(mbox_filename, 200);
lv_obj_set_event_cb(mbox_filename, filename_event_handler);
lv_obj_align(mbox_filename, NULL, LV_ALIGN_IN_TOP_MID, 0, 40);
lv_kb_set_ta(kb, ta_filename);
}
static void filename_event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
lv_mbox_start_auto_close(mbox_filename, 0);
printf("Button: %s\n", lv_mbox_get_active_btn_text(obj));
home_menu();
if(strcmp(lv_mbox_get_active_btn_text(obj), "Apply")==0){
String contents = lv_ta_get_text(ta);
String fileName = lv_ta_get_text(ta_filename);
if(fileName.length() > 0){
if(writeFile("/"+fileName, contents)){
//Write Success
refresh_list();
home_menu();
}else{
//Cannot write to file
header_set_text("Cannot write to file");
}
}else{
//Check the file name
header_set_text("Check the file name");
}
}
}
}
static void file_list_event(lv_obj_t * btn, lv_event_t e){
if(e == LV_EVENT_CLICKED){
currentFileName = lv_list_get_btn_text(btn);
Serial.println(currentFileName);
header_set_text(currentFileName);
lv_tabview_set_tab_act(tv, 1, LV_ANIM_ON);
if(strcmp(currentFileName.c_str(),"New") == 0){
lv_ta_set_text(ta, "");
}else{
lv_ta_set_text(ta, openFile(currentFileName).c_str());
lv_obj_t * parent = lv_obj_get_parent(lv_obj_get_parent(ta));
lv_obj_set_size(ta, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) - 10);
lv_obj_move_background(kb);
}
}
}