Lv_win not showing full line of text

Description

lv_win cropping text sent to it as console/terminal.

What MCU/Processor/Board and compiler are you using?

ESP32

What do you want to achieve?

I edited the sample terminal app to make a serial console as a feedback mechanism for the user input. The size is 250px wide and about 100px high.

The text is being received all right but it is being cropped to the left and down.

What have you tried so far?

  1. Tried all option for LV_LABEL_LONG…
lv_label_set_long_mode(terminal_label, LV_LABEL_LONG_EXPAND);
  1. Manually adjust the label width.
lv_obj_set_width(terminal_label, 200);
  1. searched for a setting in terminal.h and lv_win.h

Code to reproduce

Screenshot and/or video

Am i missing a place to adjust some thing?

Please send a short code sample (that can be compiled separately from the rest of your code) to reproduce the issue.

Its really just an edit of the terminal sample with the button and header removed.

lv_obj_t * terminal_create(void)
{
    static lv_style_t style_bg;
    lv_style_copy(&style_bg, &lv_style_pretty);
    style_bg.body.main_color = LV_COLOR_BLACK;
    style_bg.body.grad_color = lv_color_make(0x30, 0x30, 0x30);
    style_bg.body.border.color = LV_COLOR_WHITE;
    style_bg.text.color = lv_color_make(0xE0, 0xE0, 0xE0);

    lv_coord_t hres = 250;
    lv_coord_t vres = 100;

    winterm = lv_win_create(lv_scr_act(), NULL);
    lv_win_set_style(winterm, LV_WIN_STYLE_BG, &style_bg);
    lv_obj_set_size(winterm, hres, vres);
    lv_win_set_sb_mode(winterm, LV_SB_MODE_OFF);
    lv_obj_align (winterm, NULL,LV_ALIGN_CENTER, 0, 55);

    /*Make the window's content responsive*/
    lv_win_set_layout(winterm, LV_LAYOUT_PRETTY);

    /*Create a label for the text of the terminal*/
    terminal_label = lv_label_create(winterm, NULL);
    lv_label_set_long_mode(terminal_label, LV_LABEL_LONG_EXPAND);
    lv_obj_set_width(terminal_label, 200);
    lv_label_set_static_text(terminal_label, txt_log);               /*Use the text array directly*/

    return winterm;
}

void terminal_add(const char * txt_in)
{
    if(winterm == NULL) return;                 /*Check if the window is exists*/

    uint16_t txt_len = strlen(txt_in);
    uint16_t old_len = strlen(txt_log);

    /*If the data is longer then the terminal ax size show the last part of data*/
    if(txt_len > TERMINAL_LOG_LENGTH) {
        txt_in += (txt_len - TERMINAL_LOG_LENGTH);
        txt_len = TERMINAL_LOG_LENGTH;
        old_len = 0;
    }
    /*If the text become too long 'forget' the oldest lines*/
    else if(old_len + txt_len > TERMINAL_LOG_LENGTH) {
        uint16_t new_start;
        for(new_start = 0; new_start < old_len; new_start++) {
            if(txt_log[new_start] == '\n') {
                /*If there is enough space break*/
                if(new_start >= txt_len) {
                    /*Ignore line breaks*/
                    while(txt_log[new_start] == '\n' || txt_log[new_start] == '\r') new_start++;
                    break;
                }
            }
        }

        /* If it wasn't able to make enough space on line breaks
         * simply forget the oldest characters*/
        if(new_start == old_len) {
            new_start = old_len - (TERMINAL_LOG_LENGTH - txt_len);
        }
        /*Move the remaining text to the beginning*/
        uint16_t j;
        for(j = new_start; j < old_len; j++) {
            txt_log[j - new_start] = txt_log[j];
        }
        old_len = old_len - new_start;
        txt_log[old_len] = '\0';

    }

    memcpy(&txt_log[old_len], txt_in, txt_len);
    txt_log[old_len + txt_len] = '\0';

    lv_label_set_static_text(terminal_label, txt_log);
}

I tried you code but a few hings are still missing:

  • TERMINAL_LOG_LENGTH
  • txt_log
  • terminal_label
  • winterm

These things?

#include <FS.h>
#include <SPIFFS.h>
#include <lvgl.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#include "grbl.h"
#include "terminal.h"

#define FORMAT_SPIFFS_IF_FAILED true
#define TERMINAL_ANIM_TIME 100
#define TERMINAL_NO_INPUT 0
#define TERMINAL_LOG_LENGTH 512

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
int screenWidth = 480;
int screenHeight = 320;

const char * GCode = "f";
static const int buzzerPin = 0;

static lv_obj_t * winterm;
static char txt_log[TERMINAL_LOG_LENGTH + 1];
static lv_obj_t * terminal_label;
#define TERMINAL_LOG_LENGTH 512
static char txt_log[TERMINAL_LOG_LENGTH + 1];
static lv_obj_t * terminal_label;


lv_obj_t * terminal_create(void)
{
    static lv_style_t style_bg;
    lv_style_copy(&style_bg, &lv_style_pretty);
    style_bg.body.main_color = lv_color_make(0x30, 0x30, 0x30);
    style_bg.body.grad_color = lv_color_make(0x30, 0x30, 0x30);
    style_bg.body.border.color = LV_COLOR_WHITE;
    style_bg.text.color = lv_color_make(0xE0, 0xE0, 0xE0);

    lv_coord_t hres = 350;
    lv_coord_t vres = 100;

    win = lv_win_create(lv_disp_get_scr_act(NULL), NULL);
    lv_win_set_style(win, LV_WIN_STYLE_BG, &style_bg);
    lv_obj_set_size(win, hres, vres);
    lv_obj_set_pos(win,115,160);
    lv_win_set_sb_mode(win, LV_SB_MODE_AUTO);
    
    /*Make the window's content responsive*/
    lv_win_set_layout(win, LV_LAYOUT_PRETTY);

    /*Create a label for the text of the terminal*/
    terminal_label = lv_label_create(win, NULL);
    lv_obj_set_width(terminal_label, lv_win_get_width(win));
    lv_label_set_long_mode(terminal_label, LV_LABEL_LONG_EXPAND);
    lv_label_set_static_text(terminal_label, txt_log);               /*Use the text array directly*/

    return win;
}
/* 
Add Lines to terminal console
*/
void terminal_add(const char * txt_in)
{
    if(win == NULL) return;                 /*Check if the window is exists*/

    size_t txt_len = strlen(txt_in);
    size_t old_len = strlen(txt_log);

    /*If the data is longer then the terminal ax size show the last part of data*/
    if(txt_len > TERMINAL_LOG_LENGTH) {
        txt_in += (txt_len - TERMINAL_LOG_LENGTH);
        txt_len = TERMINAL_LOG_LENGTH;
        old_len = 0;
    }
    /*If the text become too long 'forget' the oldest lines*/
    else if(old_len + txt_len > TERMINAL_LOG_LENGTH) {
        uint16_t new_start;
        for(new_start = 0; new_start < old_len; new_start++) {
            if(txt_log[new_start] == '\n') {
                /*If there is enough space break*/
                if(new_start >= txt_len) {
                    /*Ignore line breaks*/
                    while(txt_log[new_start] == '\n' || txt_log[new_start] == '\r') new_start++;
                    break;
                }
            }
        }

        /* If it wasn't able to make enough space on line breaks
         * simply forget the oldest characters*/
        if(new_start == old_len) {
            new_start = old_len - (TERMINAL_LOG_LENGTH - txt_len);
        }
        /*Move the remaining text to the beginning*/
        uint16_t j;
        for(j = new_start; j < old_len; j++) {
            txt_log[j - new_start] = txt_log[j];
        }
        old_len = old_len - new_start;
        txt_log[old_len] = '\0';

    }

    memcpy(&txt_log[old_len], txt_in, txt_len);
    txt_log[old_len + txt_len] = '\0';

    lv_label_set_static_text(terminal_label, txt_log);
}

I’ve tried you code like this and it seems working for me:


        terminal_create();
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");
        terminal_add("Hello world\n");

log

1 Like

There might be something wrong on how i implement it then. Thanks