112 lines
3.3 KiB
C
112 lines
3.3 KiB
C
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
|
|
#include "lvgl.h"
|
|
#include "esp_lvgl_port.h"
|
|
|
|
#include "lcd/ui_log.h"
|
|
#include "lcd/ui_internal.h"
|
|
|
|
#define UI_LOG_MAX_LINES 41
|
|
#define UI_LOG_LINE_MAX_LENGTH 160
|
|
|
|
static lv_obj_t *log_textarea = NULL;
|
|
static char log_lines[UI_LOG_MAX_LINES][UI_LOG_LINE_MAX_LENGTH];
|
|
static size_t log_line_length = 0;
|
|
static size_t log_line_start = 0;
|
|
|
|
static size_t ui_log_buffer_index(size_t line_offset){
|
|
return (log_line_start + line_offset) % UI_LOG_MAX_LINES;
|
|
}
|
|
|
|
static const char *ui_log_store_line(const char *text, bool *out_evicted){
|
|
size_t line_index;
|
|
bool evicted = false;
|
|
|
|
if(log_line_length < UI_LOG_MAX_LINES){
|
|
line_index = ui_log_buffer_index(log_line_length);
|
|
log_line_length++;
|
|
}
|
|
else{
|
|
line_index = log_line_start;
|
|
log_line_start = ui_log_buffer_index(1);
|
|
evicted = true;
|
|
}
|
|
|
|
snprintf(log_lines[line_index], sizeof(log_lines[line_index]), "%s", text);
|
|
*out_evicted = evicted;
|
|
return log_lines[line_index];
|
|
}
|
|
|
|
static void ui_log_append_line_locked(const char *line){
|
|
lv_textarea_add_text(log_textarea, line);
|
|
lv_textarea_add_text(log_textarea, "\n");
|
|
lv_textarea_set_cursor_pos(log_textarea, LV_TEXTAREA_CURSOR_LAST);
|
|
}
|
|
|
|
static void ui_log_render_all_locked(void){
|
|
lv_textarea_set_text(log_textarea, "");
|
|
for(size_t line_offset = 0; line_offset < log_line_length; line_offset++){
|
|
lv_textarea_add_text(log_textarea, log_lines[ui_log_buffer_index(line_offset)]);
|
|
lv_textarea_add_text(log_textarea, "\n");
|
|
}
|
|
lv_textarea_set_cursor_pos(log_textarea, LV_TEXTAREA_CURSOR_LAST);
|
|
}
|
|
|
|
void ui_log_append(const char *text){
|
|
if(text == NULL) return;
|
|
|
|
bool evicted = false;
|
|
const char *stored_line = ui_log_store_line(text, &evicted);
|
|
if(log_textarea == NULL) return;
|
|
|
|
lvgl_port_lock(0);
|
|
if(evicted) ui_log_render_all_locked();
|
|
else ui_log_append_line_locked(stored_line);
|
|
lvgl_port_unlock();
|
|
}
|
|
|
|
void ui_log_appendf(const char *format, ...){
|
|
if(format == NULL) return;
|
|
|
|
char line[UI_LOG_LINE_MAX_LENGTH];
|
|
va_list args;
|
|
va_start(args, format);
|
|
vsnprintf(line, sizeof(line), format, args);
|
|
va_end(args);
|
|
|
|
ui_log_append(line);
|
|
}
|
|
|
|
void ui_log_detach(void){
|
|
log_textarea = NULL;
|
|
}
|
|
|
|
void ui_log_build_view(lv_obj_t *screen){
|
|
ui_attach_toggle(screen);
|
|
lv_obj_set_style_bg_color(screen, lv_color_hex(0x101418), 0);
|
|
|
|
lv_obj_t *title = lv_label_create(screen);
|
|
ui_attach_toggle(title);
|
|
lv_label_set_text(title, "SD Image Viewer");
|
|
lv_obj_set_style_text_color(title, lv_color_white(), 0);
|
|
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 14);
|
|
|
|
log_textarea = lv_textarea_create(screen);
|
|
ui_attach_toggle(log_textarea);
|
|
lv_obj_set_size(log_textarea, 440, 730);
|
|
lv_obj_align(log_textarea, LV_ALIGN_TOP_LEFT, 20, 40);
|
|
lv_textarea_set_one_line(log_textarea, false);
|
|
lv_textarea_set_cursor_click_pos(log_textarea, false);
|
|
lv_textarea_set_text(log_textarea, "");
|
|
lv_obj_set_style_bg_color(log_textarea, lv_color_hex(0x182028), 0);
|
|
lv_obj_set_style_text_color(log_textarea, lv_color_hex(0xdde7ef), 0);
|
|
lv_obj_set_style_border_color(log_textarea, lv_color_hex(0x4b6478), 0);
|
|
lv_obj_set_style_radius(log_textarea, 4, 0);
|
|
lv_obj_set_style_pad_all(log_textarea, 12, 0);
|
|
|
|
ui_log_render_all_locked();
|
|
}
|