@@ -1749,6 +1749,13 @@ void EPD_clearStringRect(int x, int y, char *str) | |||
EPD_fillRect(x+dispWin.x1, y+dispWin.y1, w, h, _bg); | |||
} | |||
void EPD_frameStringRect(int x, int y, char *str) | |||
{ | |||
int w = EPD_getStringWidth(str); | |||
int h = EPD_getfontheight(); | |||
EPD_drawRect(x+dispWin.x1, y+dispWin.y1, w, h, _fg); | |||
} | |||
//============================================================================== | |||
/** | |||
* bit-encoded bar position of all digits' bcd segments | |||
@@ -529,6 +529,10 @@ int EPD_getStringWidth(char* str); | |||
*/ | |||
void EPD_clearStringRect(int x, int y, char *str); | |||
/* | |||
* Frames the rectangle occupied by string with current foreground color | |||
*/ | |||
void EPD_frameStringRect(int x, int y, char *str); | |||
/* | |||
* Compile font c source file to .fnt file | |||
@@ -1,5 +1,5 @@ | |||
FILE(GLOB_RECURSE app_sources *.cpp *.c) | |||
set(COMPONENT_SRCS "${app_sources} main.cpp") | |||
set(COMPONENT_SRCS "${app_sources}" "main.cpp") | |||
set(COMPONENT_ADD_INCLUDEDIRS "." "../components/") | |||
register_component() |
@@ -111,3 +111,11 @@ void display_sleep() | |||
{ | |||
EPD_PowerOff(); | |||
} | |||
void display_alert(char* text) | |||
{ | |||
EPD_clearStringRect(CENTER, CENTER, text); | |||
EPD_print(text, CENTER, CENTER); | |||
EPD_frameStringRect(CENTER, CENTER, text); | |||
EPD_UpdateScreen(); | |||
} |
@@ -14,6 +14,8 @@ void display_update(); | |||
void display_wake(); | |||
void display_sleep(); | |||
void display_alert(char* text); | |||
#ifdef __cplusplus | |||
} | |||
#endif |
@@ -6,8 +6,6 @@ | |||
#include <string.h> | |||
#include "esp_system.h" | |||
#include "driver/gpio.h" | |||
#include "esp_system.h" | |||
#include "esp_heap_alloc_caps.h" | |||
#include "esp_log.h" | |||
static const char *TAG = "main"; | |||
@@ -1,7 +1,9 @@ | |||
#include <string.h> | |||
#include "core/common.h" | |||
#include "core/buttons.h" | |||
#include "core/display.h" | |||
#include <epaper/EPD.h> | |||
#include "reader/reader_storage.h" | |||
#include "InternalMemoryMenuMode.h" | |||
void InternalMemoryMenuMode::start() | |||
@@ -18,14 +20,25 @@ void InternalMemoryMenuMode::loop() | |||
EPD_print("Internal Memory", CENTER, 00); | |||
EPD_setFont(DEJAVU18_FONT, NULL); | |||
EPD_print("Current File:", 5, 30); | |||
EPD_print("/spiffs/book.txt", 20, 50); | |||
EPD_print("Size:", 5, 80); | |||
EPD_print("1234 kB", 100, 80); | |||
// TODO: free memory? | |||
EPD_print("Size:", 5, 40); | |||
long length = reader_storage_get_length(); | |||
if (length < 0) { | |||
strcpy(text, "unknown"); | |||
} else { | |||
sprintf(text, "%ld kB", length / 1024); | |||
} | |||
EPD_print(text, 100, 40); | |||
EPD_print("Position:", 5, 100); | |||
EPD_print("45%", 100, 100); | |||
EPD_print("Position:", 5, 70); | |||
long position = reader_storage_get_position(); | |||
if (position < 0) { | |||
strcpy(text, "unknown"); | |||
} else { | |||
sprintf(text, "%d%%", (int)(position * 100 / length)); | |||
} | |||
EPD_print(text, 100, 70); | |||
display_update(); | |||
while (1) { | |||
@@ -2,6 +2,7 @@ | |||
#include "string.h" | |||
#include "core/buttons.h" | |||
#include "core/display.h" | |||
#include "reader/reader_storage.h" | |||
#include "ReaderMode.h" | |||
#include "esp_log.h" | |||
@@ -11,7 +12,20 @@ static const char *TAG = "ReaderMode"; | |||
void ReaderMode::start() | |||
{ | |||
this->textReader = textStorage.open("/sdcard/book.txt"); | |||
char filename[64]; | |||
reader_storage_get_filename(filename, sizeof(filename)); | |||
this->textReader = textStorage.open(filename); | |||
this->bookmark_max = reader_storage_get_length(); | |||
this->bookmark = reader_storage_get_position(); | |||
if (this->bookmark_max < 0) { | |||
this->bookmark_max = 0; | |||
} | |||
if (this->bookmark < 0 || this->bookmark > this->bookmark_max) { | |||
this->bookmark = 0; | |||
} | |||
ESP_LOGI(TAG, "Opening %s for reading at %ld / %ld.", | |||
filename, bookmark, bookmark_max); | |||
} | |||
void ReaderMode::loop() | |||
@@ -42,7 +56,11 @@ void ReaderMode::loop() | |||
} | |||
display_clear(); | |||
pagePrinter.print(pageCurrent); | |||
if (bookmark == bookmark_max) { | |||
display_alert("THE END"); | |||
} else { | |||
pagePrinter.print(pageCurrent); | |||
} | |||
display_update(); | |||
//time_t idleStart = clock(); | |||
@@ -57,7 +75,10 @@ void ReaderMode::loop() | |||
ESP_LOGI(TAG, "Turn page PLUS."); | |||
if (pageCurrent != NULL) { | |||
bookmark = pageCurrent->start + pageCurrent->len; | |||
// TODO: limit bookmark to file size | |||
if (bookmark > bookmark_max) { | |||
bookmark = bookmark_max; | |||
} | |||
reader_storage_set_position(bookmark); | |||
typesetter.destroyPage(pageLast); | |||
pageLast = pageCurrent; | |||
pageCurrent = NULL; | |||
@@ -70,6 +91,7 @@ void ReaderMode::loop() | |||
ESP_LOGI(TAG, "Turn page MINUS."); | |||
if (pageLast != NULL) { | |||
bookmark = pageLast->start; | |||
reader_storage_set_position(bookmark); | |||
typesetter.destroyPage(pageCurrent); | |||
pageCurrent = pageLast; | |||
pageLast = NULL; | |||
@@ -12,6 +12,7 @@ public: | |||
private: | |||
long bookmark = 0; | |||
long bookmark_max = 0; | |||
Typesetter typesetter; | |||
PagePrinter pagePrinter; | |||
TextStorage textStorage; | |||
@@ -8,11 +8,14 @@ | |||
#include <sys/stat.h> | |||
#include <sys/types.h> | |||
#include <dirent.h> | |||
#include "reader/reader_storage.h" | |||
#include "SdCardMenuMode.h" | |||
#include "esp_log.h" | |||
static char* TAG = "SdCardMenuMode"; | |||
#define SDCARD_BASEDIR "/sdcard/" | |||
// TODO: make use of bytes | |||
void SdCardMenuMode::start() | |||
@@ -104,7 +107,15 @@ void SdCardMenuMode::onOptionSelected(int option) | |||
this->setFinished(); | |||
return; | |||
} | |||
// TODO files | |||
// TODO: spawn a copy AppMode | |||
display_alert("Copying into internal memory..."); | |||
char source[64]; | |||
strcpy(source, SDCARD_BASEDIR); | |||
strcat(source, this->options[option]); | |||
reader_storage_store_file(source); | |||
reader_storage_set_position(0); | |||
this->setFinished(); | |||
} | |||
int SdCardMenuMode::getOptionsX() | |||
@@ -31,13 +31,6 @@ size_t TextReader::read(long pos, char* text, size_t len) | |||
} else { | |||
fseek(this->f, pos, SEEK_SET); | |||
size_t read = fread(text, 1, len, this->f); | |||
if (read > 0) { | |||
//ESP_LOGI(TAG, "Read content: %s", text); | |||
} else { | |||
ESP_LOGI(TAG, "End of file. Closing."); | |||
fclose(this->f); | |||
this->f = NULL; | |||
} | |||
return read; | |||
} | |||
} |
@@ -8,7 +8,7 @@ TextStorage::TextStorage() | |||
TextReader* TextStorage::open(char* filename) | |||
{ | |||
FILE* f = fopen("/sdcard/book.txt", "r"); | |||
FILE* f = fopen(filename, "r"); | |||
if (f == NULL) { | |||
ESP_LOGE(TAG, "File could not be opened"); | |||
return NULL; | |||
@@ -0,0 +1,135 @@ | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
#include <sys/stat.h> | |||
#include <sys/types.h> | |||
#include "esp_system.h" | |||
#include "spiffs/spiffs_vfs.h" | |||
#include "esp_log.h" | |||
static const char *TAG = "reader_storage"; | |||
static const char* filename_stored = "stored.dat"; | |||
static const char* filename_position = "position.dat"; | |||
static int check_storage_ready() | |||
{ | |||
if (spiffs_is_mounted == 0) { | |||
ESP_LOGE(TAG, "Reader storage is not mounted."); | |||
} | |||
return spiffs_is_mounted; | |||
} | |||
void reader_storage_get_filename(char* buf, int len) | |||
{ | |||
if (check_storage_ready() == 0) { | |||
return; | |||
} | |||
strcpy(buf, SPIFFS_BASE_PATH); | |||
strcat(buf, "/"); | |||
strcat(buf, filename_stored); | |||
} | |||
long reader_storage_get_length() | |||
{ | |||
if (check_storage_ready() == 0) { | |||
return -1; | |||
} | |||
char path[64]; | |||
reader_storage_get_filename(path, sizeof(path)); | |||
long length = -1; | |||
struct stat stats; | |||
if (stat(path, &stats) == 0) { | |||
length = stats.st_size; | |||
} | |||
ESP_LOGI(TAG, "Getting length: %ld", length); | |||
return length; | |||
} | |||
void reader_storage_store_file(char* source_path) | |||
{ | |||
if (check_storage_ready() == 0) { | |||
return; | |||
} | |||
char dest_path[64]; | |||
reader_storage_get_filename(dest_path, sizeof(dest_path)); | |||
ESP_LOGI(TAG, "Storing file %s into %s", source_path, dest_path); | |||
FILE* src = fopen(source_path, "r"); | |||
if (src == NULL) { | |||
ESP_LOGE(TAG, "Failed opening source file."); | |||
return; | |||
} | |||
FILE* dst = fopen(dest_path, "w"); | |||
if (dst == NULL) { | |||
ESP_LOGE(TAG, "Failed opening destination file."); | |||
return; | |||
} | |||
char buf[32]; | |||
int len = 0; | |||
do { | |||
len = fread(buf, 1, sizeof(buf), src); | |||
if (len > 0) { | |||
len = fwrite(buf, 1, sizeof(buf), dst); | |||
} | |||
} while (len > 0); | |||
fclose(dst); | |||
fclose(src); | |||
ESP_LOGI(TAG, "File stored."); | |||
} | |||
long reader_storage_get_position() | |||
{ | |||
if (check_storage_ready() == 0) { | |||
return -1; | |||
} | |||
long position = 0; | |||
char* path[64]; | |||
strcpy(path, SPIFFS_BASE_PATH); | |||
strcat(path, "/"); | |||
strcat(path, filename_position); | |||
FILE* f = fopen(path, "r"); | |||
if (f == NULL) { | |||
ESP_LOGE(TAG, "Failed opening position file for reading."); | |||
return; | |||
} | |||
if (fread(&position, sizeof(position), 1, f) != 1) { | |||
ESP_LOGE(TAG, "Failed reading position."); | |||
position = -1; | |||
} | |||
fclose(f); | |||
ESP_LOGI(TAG, "Getting position: %ld", position); | |||
return position; | |||
} | |||
void reader_storage_set_position(long position) | |||
{ | |||
if (check_storage_ready() == 0) { | |||
return; | |||
} | |||
ESP_LOGI(TAG, "Setting position: %ld", position); | |||
char* path[64]; | |||
strcpy(path, SPIFFS_BASE_PATH); | |||
strcat(path, "/"); | |||
strcat(path, filename_position); | |||
FILE* f = fopen(path, "w"); | |||
if (f == NULL) { | |||
ESP_LOGE(TAG, "Failed opening position file for writing."); | |||
return; | |||
} | |||
if (fwrite(&position, sizeof(position), 1, f) != 1) { | |||
ESP_LOGE(TAG, "Failed writing position."); | |||
} | |||
fclose(f); | |||
} |
@@ -0,0 +1,14 @@ | |||
#include <stdlib.h> | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
void reader_storage_get_filename(char* buf, int len); | |||
long reader_storage_get_length(); | |||
void reader_storage_store_file(char* source_path); | |||
long reader_storage_get_position(); | |||
void reader_storage_set_position(long position); | |||
#ifdef __cplusplus | |||
} | |||
#endif |