Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ build_flags =
-DLV_USE_FS_STDIO=0
-DLV_USE_FS_POSIX=0
-DLV_USE_IME_PINYIN=1
-DLVGL_DRAW_BUF_DIV=4
-DLVGL_DRAW_BUF_DIV=2
-DLVGL_DOUBLE_BUF=1
-DLV_MEM_POOL_SIZE_KB=384
-DCORE_DEBUG_LEVEL=0
Expand All @@ -42,7 +42,7 @@ build_flags =
-DARDUINO_LOOP_STACK_SIZE=16384
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
-Os
-O2
lib_deps =
bodmer/TFT_eSPI@^2.5.43
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git#v1.4
Expand Down
6 changes: 3 additions & 3 deletions src/Setup_ESP32_2432S028R_ILI9341.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 27000000
#define SPI_FREQUENCY 55000000
#define SPI_FREQUENCY 80000000
// #define SPI_FREQUENCY 55000000
// #define SPI_FREQUENCY 80000000

Expand All @@ -380,8 +380,8 @@
// then uncomment the following line:
#define USE_HSPI_PORT

// Enable TFT_eSPI DMA path on classic ESP32 to improve flush throughput.
#define ESP32_DMA
// DMA disabled: causes screen corruption on this hardware.
// #define ESP32_DMA

// Comment out the following #define if "SPI Transactions" do not need to be
// supported. When commented out the code size will be smaller and sketches will
Expand Down
8 changes: 5 additions & 3 deletions src/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,12 @@ class AppManager {
if (bytes_read == 0 && read_chunk_file_size > 0) return false;

read_chunk_bytes = bytes_read;
bool has_prev = read_chunk_index > 0;
bool has_next = ((uint64_t)offset + (uint64_t)read_chunk_bytes) < read_chunk_file_size;

editor.setTitle(current_filename);
editor.setReadChunkMode(true);
editor.setReadChunkNavigationState(read_chunk_index > 0, ((uint64_t)offset + (uint64_t)read_chunk_bytes) < read_chunk_file_size);
editor.setReadChunkText(content, anchor_end);
editor.setReadChunkText(content, has_prev, has_next, anchor_end);
return true;
}

Expand Down Expand Up @@ -512,7 +514,7 @@ class AppManager {
if (dot < 0) return false;
String ext = path.substring(dot + 1);
ext.toLowerCase();
return (ext == "jpg" || ext == "jpeg");
return (ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "bmp" || ext == "gif");
}

void showPrevImage() {
Expand Down
22 changes: 11 additions & 11 deletions src/lv_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
* and can't be drawn in chunks. */

/*The target buffer size for simple layer chunks.*/
#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (12 * 1024) /*[bytes]*/
#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/

/* The stack size of the drawing thread.
* NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more.
Expand Down Expand Up @@ -190,13 +190,13 @@
/*Allow buffering some shadow calculation.
*LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
*Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/
#define LV_DRAW_SW_SHADOW_CACHE_SIZE 0
#define LV_DRAW_SW_SHADOW_CACHE_SIZE 128

/* Set number of maximally cached circle data.
* The circumference of 1/4 circle are saved for anti-aliasing
* radius * 4 bytes are used per circle (the most often used radiuses are saved)
* 0: to disable caching */
#define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4
#define LV_DRAW_SW_CIRCLE_CACHE_SIZE 32
#endif

#define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE
Expand Down Expand Up @@ -381,11 +381,11 @@
*Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory.
*If size is not set to 0, the decoder will fail to decode when the cache is full.
*If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/
#define LV_CACHE_DEF_SIZE 0
#define LV_CACHE_DEF_SIZE (64 * 1024)

/*Default number of image header cache entries. The cache is used to store the headers of images
*The main logic is like `LV_CACHE_DEF_SIZE` but for image headers.*/
#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0
#define LV_IMAGE_HEADER_CACHE_DEF_CNT 8

/*Number of stops allowed per gradient. Increase this to allow more stops.
*This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
Expand All @@ -396,7 +396,7 @@
#define LV_COLOR_MIX_ROUND_OFS 0

/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */
#define LV_OBJ_STYLE_CACHE 0
#define LV_OBJ_STYLE_CACHE 1

/* Add `id` field to `lv_obj_t` */
#define LV_USE_OBJ_ID 0
Expand Down Expand Up @@ -703,8 +703,8 @@
/*0: Light mode; 1: Dark mode*/
#define LV_THEME_DEFAULT_DARK 0

/*1: Enable grow on press*/
#define LV_THEME_DEFAULT_GROW 1
/*0: Disable grow on press to eliminate extra redraw area during press animations*/
#define LV_THEME_DEFAULT_GROW 0

/*Default transition time in [ms]*/
#define LV_THEME_DEFAULT_TRANSITION_TIME 80
Expand Down Expand Up @@ -791,13 +791,13 @@
#endif

/*LODEPNG decoder library*/
#define LV_USE_LODEPNG 0
#define LV_USE_LODEPNG 1

/*PNG decoder(libpng) library*/
#define LV_USE_LIBPNG 0

/*BMP decoder library*/
#define LV_USE_BMP 0
#define LV_USE_BMP 1

/* JPG + split JPG decoder library.
* Split JPG is a custom format optimized for embedded systems. */
Expand All @@ -808,7 +808,7 @@
#define LV_USE_LIBJPEG_TURBO 0

/*GIF decoder library*/
#define LV_USE_GIF 0
#define LV_USE_GIF 1
#if LV_USE_GIF
/*GIF decoder accelerate*/
#define LV_GIF_CACHE_DECODE_DATA 0
Expand Down
47 changes: 43 additions & 4 deletions src/ui/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Editor {
static constexpr uint8_t IME_CAND_PER_PAGE = 8;
static constexpr uint16_t IME_CAND_MAX = 160;
static constexpr size_t LARGE_DOC_PERF_THRESHOLD = 2 * 1024;
static constexpr int32_t TEXTAREA_SCROLL_ANIM_MS = 260;
static constexpr int32_t CHUNK_NAV_BTN_SIZE = 24;
static constexpr lv_opa_t CHUNK_NAV_BTN_BG_OPA = static_cast<lv_opa_t>((LV_OPA_COVER * 75) / 100);
lv_obj_t* screen;
Expand Down Expand Up @@ -199,7 +200,7 @@ class Editor {
lv_obj_set_style_width(textarea, 1, LV_PART_CURSOR);
lv_obj_add_flag(textarea, LV_OBJ_FLAG_SCROLL_ELASTIC);
lv_obj_add_flag(textarea, LV_OBJ_FLAG_SCROLL_MOMENTUM);
lv_obj_set_style_anim_duration(textarea, 260, 0);
lv_obj_set_style_anim_duration(textarea, TEXTAREA_SCROLL_ANIM_MS, 0);
int32_t editor_cursor_h = EDITOR_TEXT_SIZE_PX;
if (editor_cursor_h < 2) editor_cursor_h = 2;
lv_obj_set_style_height(textarea, editor_cursor_h, LV_PART_CURSOR);
Expand Down Expand Up @@ -365,12 +366,50 @@ class Editor {
refreshReadChunkButtons();
}

void setReadChunkText(const String& content, bool anchor_end) {
void setReadChunkText(const String& content, bool has_prev, bool has_next, bool anchor_end) {
if (!textarea) return;

// Suppress scroll animations during content swap so that the
// internal auto-scroll triggered by lv_textarea_set_text() does
// not conflict with the explicit scroll below. This is the root
// cause of the visible "scroll-up jump" on every chunk switch.
lv_obj_set_style_anim_duration(textarea, 0, 0);

applyLargeDocPerfMode(content.length());

// Batch-update navigation state before the final button refresh.
read_chunk_has_prev = has_prev;
read_chunk_has_next = has_next;

// Replace content. LVGL internally moves the cursor to the end
// of the new text and auto-scrolls, but with anim_duration == 0
// the scroll is instantaneous and invisible.
lv_textarea_set_text(textarea, content.c_str());
if (anchor_end) moveCursorAndViewToEnd();
else moveCursorAndViewToStart();

// Set cursor and record anchor for IME.
if (anchor_end) {
uint32_t len = (uint32_t)content.length();
lv_textarea_set_cursor_pos(textarea, (int32_t)len);
ime_cursor_anchor_pos = len;
} else {
lv_textarea_set_cursor_pos(textarea, 0);
ime_cursor_anchor_pos = 0;
}
ime_cursor_anchor_valid = true;

// Force layout so scroll metrics are accurate, then set the
// definitive scroll position in one shot.
lv_obj_update_layout(textarea);
if (anchor_end) {
int32_t bottom = lv_obj_get_scroll_bottom(textarea);
if (bottom > 0) lv_obj_scroll_by(textarea, 0, bottom, LV_ANIM_OFF);
} else {
lv_obj_scroll_to_y(textarea, 0, LV_ANIM_OFF);
}

// Restore normal scroll animation for user interaction.
lv_obj_set_style_anim_duration(textarea, TEXTAREA_SCROLL_ANIM_MS, 0);

clearReadChunkFocus();
refreshReadChunkButtons();
}
Expand Down
Loading