#include <Preferences.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <stdio.h>
#define TFT_SCK 18
#define TFT_MOSI 23
#define TFT_DC 22
#define TFT_RESET 21
#define TFT_SPIBUS VSPI_HOST
#define FORMAT_ON_FAIL true
#define SPIFFS_MOUNT_PATH "/flash"
#define SDCARD_MOUNT_PATH "/SD"
Preferences preferences;
class MyApp : public uiApp {
uiLabel * WiFiStatusLbl;
uiFileBrowser * fileBrowser;
uiLabel * freeSpaceLbl;
void init() {
rootWindow()->frameStyle().backgroundColor = RGB888(255, 255, 255);
fileBrowser = new uiFileBrowser(rootWindow(), Point(10, 5), Size(130, 170));
fileBrowser->setDirectory("/");
fileBrowser->onChange = [&]() {
updateFreeSpaceLabel();
};
auto createDirBtn = new uiButton(rootWindow(), "Create Dir", Point(150, 5), Size(80, 20));
createDirBtn->onClick = [&]() {
constexpr int MAXSTRLEN = 16;
char dirname[MAXSTRLEN + 1] = "";
if (inputBox("Create Directory", "Name", dirname, MAXSTRLEN, "Create", "Cancel") == uiMessageBoxResult::Button1) {
fileBrowser->content().makeDirectory(dirname);
updateBrowser();
}
};
auto createEmptyFile = new uiButton(rootWindow(), "Create File", Point(150, 30), Size(80, 20));
createEmptyFile->onClick = [&]() {
constexpr int MAXSTRLEN = 16;
char filename[MAXSTRLEN + 1] = "";
if (inputBox("Create Empty File", "Name", filename, MAXSTRLEN, "Create", "Cancel") == uiMessageBoxResult::Button1) {
int len = fileBrowser->content().getFullPath(filename);
char fullpath[len];
fileBrowser->content().getFullPath(filename, fullpath, len);
FILE * f = fopen(fullpath, "wb");
fclose(f);
updateBrowser();
}
};
auto renameBtn = new uiButton(rootWindow(), "Rename", Point(150, 55), Size(80, 20));
renameBtn->onClick = [&]() {
int maxlen = fabgl::imax(16, strlen(fileBrowser->filename()));
char filename[maxlen + 1];
strcpy(filename, fileBrowser->filename());
if (inputBox("Rename File", "New name", filename, maxlen, "Rename", "Cancel") == uiMessageBoxResult::Button1) {
fileBrowser->content().rename(fileBrowser->filename(), filename);
updateBrowser();
}
};
auto deleteBtn = new uiButton(rootWindow(), "Delete", Point(150, 80), Size(80, 20));
deleteBtn->onClick = [&]() {
if (messageBox("Delete file/directory", "Are you sure?", "Yes", "Cancel") == uiMessageBoxResult::Button1) {
fileBrowser->content().remove( fileBrowser->filename() );
updateBrowser();
}
};
auto formatBtn = new uiButton(rootWindow(), "Format", Point(150, 105), Size(80, 20));
formatBtn->onClick = [&]() {
if (messageBox("Format sdcard", "Are you sure?", "Yes", "Cancel") == uiMessageBoxResult::Button1) {
FileBrowser::format(fileBrowser->content().getCurrentDriveType(), 0);
updateBrowser();
}
};
auto setupWifiBtn = new uiButton(rootWindow(), "Setup WiFi", Point(150, 130), Size(80, 20));
setupWifiBtn->onClick = [=]() {
char SSID[32] = "";
char psw[32] = "";
if (inputBox("WiFi Connect", "Network Name", SSID, sizeof(SSID), "OK", "Cancel") == uiMessageBoxResult::Button1 &&
inputBox("WiFi Connect", "Password", psw, sizeof(psw), "OK", "Cancel") == uiMessageBoxResult::Button1) {
preferences.putString("SSID", SSID);
preferences.putString("WiFiPsw", psw);
connectWiFi();
}
};
auto downloadBtn = new uiButton(rootWindow(), "Download", Point(150, 155), Size(80, 20));
downloadBtn->onClick = [=]() {
char URL[128] = "http://";
if (inputBox("Download File", "URL", URL, sizeof(URL), "OK", "Cancel") == uiMessageBoxResult::Button1) {
download(URL);
updateFreeSpaceLabel();
}
};
freeSpaceLbl = new uiLabel(rootWindow(), "", Point(10, 200));
updateFreeSpaceLabel();
WiFiStatusLbl = new uiLabel(rootWindow(), "", Point(10, 215));
connectWiFi();
setFocusedWindow(fileBrowser);
}
void updateBrowser()
{
fileBrowser->update();
updateFreeSpaceLabel();
}
void connectWiFi()
{
WiFiStatusLbl->setText("WiFi Not Connected");
WiFiStatusLbl->labelStyle().textColor = RGB888(255, 0, 0);
char SSID[32], psw[32];
if (preferences.getString("SSID", SSID, sizeof(SSID)) && preferences.getString("WiFiPsw", psw, sizeof(psw))) {
WiFi.begin(SSID, psw);
for (int i = 0; i < 16 && WiFi.status() != WL_CONNECTED; ++i) {
WiFi.reconnect();
delay(1000);
}
if (WiFi.status() == WL_CONNECTED) {
WiFiStatusLbl->setTextFmt("Connected to %s, IP is %s", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
WiFiStatusLbl->labelStyle().textColor = RGB888(0, 128, 0);
}
}
WiFiStatusLbl->update();
}
void download(char const * URL) {
char const * slashPos = strrchr(URL, '/');
if (slashPos) {
char filename[slashPos - URL + 1];
strcpy(filename, slashPos + 1);
HTTPClient http;
http.begin(URL);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
int fullpathLen = fileBrowser->content().getFullPath(filename);
char fullpath[fullpathLen];
fileBrowser->content().getFullPath(filename, fullpath, fullpathLen);
FILE * f = fopen(fullpath, "wb");
int len = http.getSize();
uint8_t buf[128] = { 0 };
WiFiClient * stream = http.getStreamPtr();
while (http.connected() && (len > 0 || len == -1)) {
size_t size = stream->available();
if (size) {
int c = stream->readBytes(buf, fabgl::imin(sizeof(buf), size));
fwrite(buf, c, 1, f);
if (len > 0)
len -= c;
}
}
fclose(f);
updateBrowser();
}
}
}
void updateFreeSpaceLabel() {
int64_t total, used;
FileBrowser::getFSInfo(fileBrowser->content().getCurrentDriveType(), 0, &total, &used);
freeSpaceLbl->setTextFmt("%lld KiB used, %lld KiB free", used / 1024, (total - used) / 1024);
freeSpaceLbl->update();
}
} app;
void setup()
{
preferences.begin("FileBrowser", false);
preferences.clear();
PS2Controller.
begin(PS2Preset::KeyboardPort0_MousePort1, KbdMode::GenerateVirtualKeys);
DisplayController.
begin(TFT_SCK, TFT_MOSI, TFT_DC, TFT_RESET, -1, TFT_SPIBUS);
Canvas cv(&DisplayController);
cv.clear();
cv.drawText(50, 170, "Initializing...");
cv.waitCompletion();
FileBrowser::mountSDCard(FORMAT_ON_FAIL, SDCARD_MOUNT_PATH);
FileBrowser::mountSPIFFS(FORMAT_ON_FAIL, SPIFFS_MOUNT_PATH);
}
void loop()
{
app.run(&DisplayController);
}
static void begin(gpio_num_t port0_clkGPIO, gpio_num_t port0_datGPIO, gpio_num_t port1_clkGPIO=GPIO_UNUSED, gpio_num_t port1_datGPIO=GPIO_UNUSED)
Initializes PS2 device controller.
The PS2 device controller class.
Implements ST7789 display driver controller.
void begin(SPIClass *spi, gpio_num_t DC, gpio_num_t RESX=GPIO_UNUSED, gpio_num_t CS=GPIO_UNUSED)
Initializes TFT display controller with Arduino style SPIClass object.
void setResolution(char const *modeline, int viewPortWidth=-1, int viewPortHeight=-1, bool doubleBuffered=false)
Sets TFT resolution and viewport size.
This file is the all in one include file. Application can just include this file to use FabGL library...
This file contains all classes related to FabGL Graphical User Interface.